关于JPA多对多关系,这是使用学生与教师来表示。一个Student由多个Teacher教,同样一个Teacher也可以教多个学生。Student类如下:
1 package com.yichun.bean; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 import javax.persistence.CascadeType; 7 import javax.persistence.Column; 8 import javax.persistence.Entity; 9 import javax.persistence.GeneratedValue; 10 import javax.persistence.Id; 11 import javax.persistence.JoinColumn; 12 import javax.persistence.JoinTable; 13 import javax.persistence.ManyToMany; 14 15 //关系的维护端 16 @Entity 17 public class Student { 18 private Integer id; 19 private String name; 20 private Set<Teacher> teachers = new HashSet<Teacher>(); 21 22 public Student() { 23 } 24 25 public Student(String name) { 26 this.name = name; 27 } 28 29 @Id 30 @GeneratedValue 31 public Integer getId() { 32 return id; 33 } 34 35 public void setId(Integer id) { 36 this.id = id; 37 } 38 39 @Column(length = 10, nullable = false) 40 public String getName() { 41 return name; 42 } 43 44 public void setName(String name) { 45 this.name = name; 46 } 47 48 @ManyToMany(cascade = CascadeType.REFRESH) 49 // 关联表,inverseJoinColumns被维护端, 50 @JoinTable(name = "student_teacher", inverseJoinColumns = @JoinColumn(name = "teacher_id"), joinColumns = @JoinColumn(name = "student_id")) 51 public Set<Teacher> getTeachers() { 52 return teachers; 53 } 54 55 public void setTeachers(Set<Teacher> teachers) { 56 this.teachers = teachers; 57 } 58 59 // 添加teacher与student关系 60 public void addTeacher(Teacher teacher) { 61 this.teachers.add(teacher); 62 } 63 64 // 删除teacher与student关联 65 public void removeTeacher(Teacher teacher) { 66 if (teachers.contains(teacher)) 67 this.teachers.remove(teacher); 68 } 69 70 }
Teacher类如下:
1 package com.yichun.bean; 2 3 import java.util.HashSet; 4 import java.util.Set; 5 6 import javax.persistence.CascadeType; 7 import javax.persistence.Column; 8 import javax.persistence.Entity; 9 import javax.persistence.GeneratedValue; 10 import javax.persistence.Id; 11 import javax.persistence.ManyToMany; 12 13 //关系被维护端,中间表的记录,不能由teacher删除, 14 @Entity 15 public class Teacher { 16 private Integer id; 17 private String name; 18 private Set<Student> students = new HashSet<Student>(); 19 20 public Teacher() { 21 } 22 23 public Teacher(String name) { 24 this.name = name; 25 } 26 27 @Id 28 @GeneratedValue 29 public Integer getId() { 30 return id; 31 } 32 33 public void setId(Integer id) { 34 this.id = id; 35 } 36 37 @Column(length = 10, nullable = false) 38 public String getName() { 39 return name; 40 } 41 42 public void setName(String name) { 43 this.name = name; 44 } 45 46 // 多对多基本不用级联删除 47 @ManyToMany(cascade = CascadeType.REFRESH, mappedBy = "teachers") 48 public Set<Student> getStudents() { 49 return students; 50 } 51 52 public void setStudents(Set<Student> students) { 53 this.students = students; 54 } 55 56 // id不为null返回id的hashCode,若没有id的时候,hashCode为0 57 @Override 58 public int hashCode() { 59 final int prime = 31; 60 int result = 1; 61 result = prime * result + ((id == null) ? 0 : id.hashCode()); 62 return result; 63 } 64 65 @Override 66 public boolean equals(Object obj) { 67 if (this == obj) 68 return true; 69 if (obj == null) 70 return false; 71 if (getClass() != obj.getClass()) 72 return false; 73 Teacher other = (Teacher) obj; 74 if (id == null) { 75 if (other.id != null) 76 return false; 77 } else if (!id.equals(other.id)) 78 return false; 79 return true; 80 } 81 82 }
这里Student是作为关系维护端,而Teacher是作为关系被维护端。所以当删除教师的时候,必须解除学生和教师的关联关系。代码如下:
1 /** 2 *<p> 3 * 删除老师 4 * </p> 5 * 解除学生和老师的关系 6 */ 7 @Test 8 public void deleteTeacher() { 9 EntityManagerFactory factory = Persistence 10 .createEntityManagerFactory("yichun"); 11 EntityManager manager = factory.createEntityManager(); 12 manager.getTransaction().begin(); 13 14 // 解除关系 15 Student student = manager.find(Student.class, 1); 16 Teacher teacher = manager.getReference(Teacher.class, 1); 17 student.removeTeacher(teacher); 18 19 // 删除教师 20 manager.remove(teacher); 21 22 manager.getTransaction().commit(); 23 manager.close(); 24 factory.close(); 25 }
而删除学生的时候,可以直接删除,jpa会自动解除学生与教师的关联关系,然后删除学生。
1 /** 2 *<p> 3 * 删除学生 4 * </p> 5 * 直接可以删除,hibernate会自动解除学生和老师的关系,之后删除学生 6 */ 7 @Test 8 public void deleteStudent() { 9 EntityManagerFactory factory = Persistence 10 .createEntityManagerFactory("yichun"); 11 EntityManager manager = factory.createEntityManager(); 12 manager.getTransaction().begin(); 13 14 // 删除学生 15 Student student = manager.find(Student.class, 1); 16 manager.remove(student); 17 18 manager.getTransaction().commit(); 19 manager.close(); 20 factory.close(); 21 }