JPA视频学习(五)双向多对多关联配置

1.配置persistence.xml和log4j

配置persistence.xml

<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
    http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0">
    
	<persistence-unit name="JPAManyToManyPU" transaction-type="RESOURCE_LOCAL">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>
  		<properties>
  		    <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/>
			<property name = "hibernate.connection.driver_class" value = "com.mysql.jdbc.Driver"/>
			<property name = "hibernate.connection.url" value = "jdbc:mysql://localhost:3306/jpa?useUnicode=true&amp;characterEncoding=UTF-8"/>
			<property name = "hibernate.connection.username" value = "root"/>
			<property name="hibernate.max_fetch_depth" value="3"/>
            <property name="hibernate.hbm2ddl.auto" value="update"/>  
	  	</properties>
	</persistence-unit>
  
</persistence>

配置log4j.properties

# For JBoss: Avoid to setup Log4J outside $JBOSS_HOME/server/default/deploy/log4j.xml!
# For all other servers: Comment out the Log4J listener in web.xml to activate Log4J.
log4j.rootLogger=INFO, stdout, logfile

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%n

log4j.appender.logfile=org.apache.log4j.RollingFileAppender
log4j.appender.logfile.File=/hello.log
log4j.appender.logfile.MaxFileSize=512KB
# Keep three backup files.
log4j.appender.logfile.MaxBackupIndex=3
# Pattern to output: date priority [category] - message
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n

2.配置实体bean

student:

import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;

@Entity
public class Student {

	private Integer id;
	private String name;
	private Set<Teacher> teachers=new HashSet<Teacher>();
	
	public Student(){}
	
	public Student(String name){
		this.name=name;
	}
	
	@Id @GeneratedValue
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	
	@Column(length=10,nullable=false)
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	//一般在多对多很少用到级联的操作。
	/**
	 * inverseJoinColumns关系被维护端的外键在中间表中的定义
	 * JoinColumns       关系维护端的外键在中间表中的定义
	 */
	@ManyToMany(cascade=CascadeType.REFRESH)
	@JoinTable(name="student_teacher"
	           ,inverseJoinColumns=@JoinColumn(name="teacherid")
	           ,joinColumns=@JoinColumn(name="studentid"))
	public Set<Teacher> getTeachers() {
		return teachers;
	}
	
	public void setTeachers(Set<Teacher> teachers) {
		this.teachers = teachers;
	}
	
	//关系的维护
	public void addTeachers(Teacher teacher){
		this.teachers.add(teacher);
	}
	
	public void removeTeachers(Teacher teacher){
		if(this.teachers.contains(teacher))//通过Teacher重载的hashCode方法来判断
			this.teachers.remove(teacher);
	}
}
teacher:
import java.util.HashSet;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;

import com.sun.org.apache.bcel.internal.generic.NEW;

@Entity
public class Teacher {

	private Integer id;
	private String name;
	private Set<Student> student=new HashSet<Student>();
	
	public Teacher(){}
	
	public Teacher(String name) {
		super();
		this.name = name;
	}

	@Id @GeneratedValue
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	
	@Column(length=10,nullable=false)
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
	@ManyToMany(mappedBy="teachers",cascade=CascadeType.REFRESH
			    ,fetch=FetchType.LAZY)//关系被维护端
	public Set<Student> getStudent() {
		return student;
	}
	public void setStudent(Set<Student> student) {
		this.student = student;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Teacher other = (Teacher) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		return true;
	}
	
	
	
}

3.Junit测试

package junit.test;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import org.junit.BeforeClass;
import org.junit.Test;
import com.persia.bean.Student;
import com.persia.bean.Teacher;
import com.sun.org.apache.bcel.internal.generic.NEW;

public class ManyToManyTest {

	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
	}
	
	//@Test
	public void save(){
		EntityManagerFactory factory=Persistence.createEntityManagerFactory("JPAManyToManyPU");
		EntityManager eManager=factory.createEntityManager();
		eManager.getTransaction().begin();
		   eManager.persist(new Student("学生1"));
		   eManager.persist(new Teacher("老师1"));
		eManager.getTransaction().commit();
		eManager.close();
		factory.close();
	}

	/**
	 * 建立老师与学生的关系
	 */
	//@Test
	public void buildRelation(){
		EntityManagerFactory factory=Persistence.createEntityManagerFactory("JPAManyToManyPU");
		EntityManager eManager=factory.createEntityManager();
		eManager.getTransaction().begin();
		  Student student=eManager.find(Student.class, 2);
		  student.addTeachers(eManager.getReference(Teacher.class, 2));
		//eManager.merge(arg0)直接更新即可:在托管中,且em是打开的。
		eManager.getTransaction().commit();
		eManager.close();
		factory.close();
	}
	
	/**
	 * 解除关系
	 */
	//@Test
	public void relieveRelation(){
		EntityManagerFactory factory=Persistence.createEntityManagerFactory("JPAManyToManyPU");
		EntityManager eManager=factory.createEntityManager();
		eManager.getTransaction().begin();
		  Student student=eManager.find(Student.class, 1);
		  student.removeTeachers(eManager.getReference(Teacher.class, 1));
		  //当前处于托管状态,而且em是打开着的,所以直接删除即可。
		eManager.getTransaction().commit();
		eManager.close();
		factory.close();
	}
	
	/**
	 * 删除老师
	 */
	//@Test
	public void deleteTeacher(){
		EntityManagerFactory factory=Persistence.createEntityManagerFactory("JPAManyToManyPU");
		EntityManager eManager=factory.createEntityManager();
		eManager.getTransaction().begin();
		  Student student=eManager.find(Student.class, 1);
		  Teacher teacher=eManager.getReference(Teacher.class, 1);
		  student.removeTeachers(teacher);
		  //先解除关系,再删除
		  eManager.remove(eManager.find(Teacher.class, 1));
		  //关系被维护端没有权力更新外键,此时此操作无法执行,有外键约束。
		eManager.getTransaction().commit();
		eManager.close();
		factory.close();
	}
	
	/**
	 * 删除关系维护端
	 */
	//@Test
	public void deleteStudent(){
		EntityManagerFactory factory=Persistence.createEntityManagerFactory("JPAManyToManyPU");
		EntityManager eManager=factory.createEntityManager();
		eManager.getTransaction().begin();
		 
		  eManager.remove(eManager.find(Student.class, 2));
		  //关系维护端有权力更新外键。
		eManager.getTransaction().commit();
		eManager.close();
		factory.close();
	}
}

你可能感兴趣的:(JPA视频学习(五)双向多对多关联配置)