首页 > 代码库 > JPA开发总结<五>--多对多双向关联

JPA开发总结<五>--多对多双向关联

继续多对多的双向关联学习,主要分析实例老师和学生,一个老师有多个学生,一个学生也有多个老师,可以学习前面的一对多关系来做处理,再重新说下之前说的注意事项,引包都要是javax.persistence的,确定维护者关系等,废话不说了,还是直接看代码。

老师实体类,学生为关系维护者:

/**
 * 双向多对多关联关系是一种对等关系,所以由我们自定义谁作为关系的维护端与被维护端
 * 我们选择学生作为关系的维护端,以后只能通过学生来维护两者的关系
 * 需要中间表来存放两者关系的定义
 */
@Entity
@Table(name="t_teacher")
public class Teacher {

	@Id @GeneratedValue(strategy=GenerationType.AUTO)
	private Integer id;
	@Column(length=20,nullable=false)
	private String name;
	/**
	 * 多对多关系中不要使用级联删除
	 */
	@ManyToMany(cascade=CascadeType.REFRESH,mappedBy="teachers")
	private Set<Student> students;
	
	public Teacher(){}
	
	public Teacher(String name) {
		this.name = name;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result
				+ ((students == null) ? 0 : students.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;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (students == null) {
			if (other.students != null)
				return false;
		} else if (!students.equals(other.students))
			return false;
		return true;
	}

	<!-- 省略。。。-->
	
}<span style="font-family:Microsoft YaHei;font-size:14px;">
</span>

学生实体类代码:

/**
 * Student作为多对多关系的维护端。外键,中间表等信息在这个类里定义
 * 方便对比相等操作,在remove方法中有用比较,我们重写hashcode和equals方法
 */
@Entity
@Table(name="t_student")
public class Student {

	@Id @GeneratedValue(strategy=GenerationType.AUTO)
	private Integer id;
	@Column(length=20,nullable=false)
	private String name;
	/**
	 * JoinTable表示中间表
	 * inverseJoinColumns表示关系被维护端对应的中间表的外键名
	 * joinColumns表示关系维护端对应的中间表的外键名
	 * @return
	 */
	@ManyToMany(cascade={CascadeType.REFRESH})
	@JoinTable(name="t_student_teacher",
			inverseJoinColumns=@JoinColumn(name="teacher_id"),
			joinColumns=@JoinColumn(name="student_id"))
	private Set<Teacher> teachers;
	
	/**
	 * 学生为维护者,为其指定添加老师方法
	 * @param teacher
	 */
	public void addTeacher(Teacher teacher){
		this.teachers.add(teacher);
	}
	
	/**
	 * 学生为维护者,为其指定移除老师方法
	 * @param teacher
	 */
	public void removeTeacher(Teacher teacher){
		if(this.teachers.contains(teacher)){
			this.teachers.remove(teacher);
		}
	}
	public Student() {
	}
	/**
	 * 方便初始化,最小构造函数
	 * @param name
	 */
	public Student(String name) {
		this.name = name;
	}
	
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result + ((id == null) ? 0 : id.hashCode());
		result = prime * result + ((name == null) ? 0 : name.hashCode());
		result = prime * result
				+ ((teachers == null) ? 0 : teachers.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;
		Student other = (Student) obj;
		if (id == null) {
			if (other.id != null)
				return false;
		} else if (!id.equals(other.id))
			return false;
		if (name == null) {
			if (other.name != null)
				return false;
		} else if (!name.equals(other.name))
			return false;
		if (teachers == null) {
			if (other.teachers != null)
				return false;
		} else if (!teachers.equals(other.teachers))
			return false;
		return true;
	}
	<!--省略。。 -->
}<span style="font-family:Microsoft YaHei;font-size:14px;">
</span>

测试代码:

public class ManyToMany {

	private static EntityManagerFactory factory;
	private static EntityManager em;
	@BeforeClass
	public static void setUpBeforeClass() throws Exception {
		factory = Persistence.createEntityManagerFactory("jpatest1");
		em = factory.createEntityManager();
	}

	@Test
	public void testSave() {
		
		em.getTransaction().begin(); //开启事务
		
		Student student1 = new Student("张三");
		Student student2 = new Student("李四");
		Teacher teacher1 = new Teacher("吴老师");
		Teacher teacher2 = new Teacher("张老师");
		
		em.persist(student1);
		em.persist(teacher1);
		em.persist(student2);
		em.persist(teacher2);
		
		em.getTransaction().commit(); //提交事务
		em.close(); //关闭
		factory.close(); //关闭
	}
	
	/**
	 * 建立Teacher与Student的关系
	 */
	@Test
	public void buildTS() {
		
		em.getTransaction().begin(); //开启事务
		
		//得到学生(因为学生是关系维护端)
		//学生现在处于managed状态
		Student student = em.find(Student.class, 1);
		//和吴老师建立师生关系,因为老师对象没有具体操作,我们脱管取出
		student.addTeacher(em.getReference(Teacher.class, 1));
		
		em.getTransaction().commit(); //提交事务
		em.close(); //关闭
		factory.close(); //关闭
	}
	
	/**
	 * 解除Teacher与Student的关系
	 */
	@Test
	public void removeTS() {
		
		em.getTransaction().begin(); //开启事务
		
		//得到学生(因为学生是关系维护端)
		//学生现在处于managed状态
		Student student = em.find(Student.class, 1);
		//和吴老师建立师生关系,因为老师对象没有具体操作,我们脱管取出
		student.removeTeacher(em.getReference(Teacher.class, 1));
		
		em.getTransaction().commit(); //提交事务
		em.close(); //关闭
		factory.close(); //关闭
	}
}
最近都是以贴代码为主,主要是方便日后回忆,直接从代码入手,方便快捷。。



JPA开发总结<五>--多对多双向关联