Student.java:
1 @Entity
2 public class Student {
3 @Id
4 @GeneratedValue
5 private Integer id;
6 @Column(length=10,nullable=false)
7 private String name;
8 @ManyToMany
9 @JoinTable(name="student_teacher",joinColumns=@JoinColumn(name="studentId", referencedColumnName="id"),
10 inverseJoinColumns=@JoinColumn(name="teacherId", referencedColumnName="id"))
11 private Set<Teacher> teachers=new HashSet<Teacher>();
12 /*假如不對關聯表裡的欄位做任何設定,那麼表裡面的欄位預設由JPA的實現產品來幫我們自動產生。
13 inverseJoinColumns:inverse中文是反轉的意思,但是覺得太噁心了,在JPA裡,可以理解為被維護端。
14 inverseJoinColumns:被維護端外鍵的定義。
15 @JoinColumn:外鍵,設定中間表跟teacher表的主鍵關聯的那個外鍵的名稱。
16 joinColumns:關係維護端的定義。*/
17 public Student(){}
18 public Student(String name) {
19 super();
20 this.name = name;
21 }
22 public Integer getId() {
23 return id;
24 }
25 public void setId(Integer id) {
26 this.id = id;
27 }
28 public String getName() {
29 return name;
30 }
31 public void setName(String name) {
32 this.name = name;
33 }
34 public Set<Teacher> getTeachers() {
35 return teachers;
36 }
37 public void setTeachers(Set<Teacher> teachers) {
38 this.teachers = teachers;
39 }
40
41 }
Teacher.java:
1 @Entity
2 public class Teacher {
3 @Id
4 @GeneratedValue
5 private Integer id;
6 @Column(length=10,nullable=false)
7 private String name;
8 @ManyToMany(mappedBy="teachers")//關係交給Student端維護
9 private Set<Student> students=new HashSet<Student>();
10 public Teacher(){}
11 public Teacher(String name) {
12 super();
13 this.name = name;
14 }
15 public Integer getId() {
16 return id;
17 }
18 public void setId(Integer id) {
19 this.id = id;
20 }
21 public String getName() {
22 return name;
23 }
24 public void setName(String name) {
25 this.name = name;
26 }
27 public Set<Student> getStudents() {
28 return students;
29 }
30 public void setStudents(Set<Student> students) {
31 this.students = students;
32 }
33
34 }
測試:
1 @Test
2 public void save(){//儲存實體
3 EntityManagerFactory factory=Persistence.createEntityManagerFactory("sample");
4 EntityManager em=factory.createEntityManager();
5 em.getTransaction().begin();
6 em.persist(new Teacher("teacher"));
7 em.persist(new Student("student"));
8 em.getTransaction().commit();
9 em.close();
10 factory.close();
11 }
12 @Test
13 public void buildRelation(){//建立實體間關係
14 EntityManagerFactory factory=Persistence.createEntityManagerFactory("sample");
15 EntityManager em=factory.createEntityManager();
16 em.getTransaction().begin();
17 Student student=em.find(Student.class, 1);
18 Teacher teacher=em.getReference(Teacher.class, 1);//getReference消極式載入,可提高效能
19 student.getTeachers().add(teacher);
20 em.getTransaction().commit();
21 em.close();
22 factory.close();
23 }
24 @Test
25 public void deleteRelation(){//解除實體間關係
26 EntityManagerFactory factory=Persistence.createEntityManagerFactory("sample");
27 EntityManager em=factory.createEntityManager();
28 em.getTransaction().begin();
29 Student student=em.find(Student.class, 1);
30 Teacher teacher=em.getReference(Teacher.class, 1);//getReference消極式載入,可提高效能
31 student.getTeachers().remove(teacher);
32 em.getTransaction().commit();
33 em.close();
34 factory.close();
35 }
36 @Test
37 public void deleteTeacher(){//刪除老師,必須先刪除中間表中得關係,才能刪除老師
38 EntityManagerFactory factory=Persistence.createEntityManagerFactory("sample");
39 EntityManager em=factory.createEntityManager();
40 em.getTransaction().begin();
41 Student student=em.find(Student.class, 1);
42 Teacher teacher=em.getReference(Teacher.class, 1);//getReference消極式載入,可提高效能
43 student.getTeachers().remove(teacher);
44 em.remove(teacher);
45 em.getTransaction().commit();
46 em.close();
47 factory.close();
48 }
49 @Test
50 public void deleteStudent(){//刪除學生,因為學生端是關係維護端,不用手動刪除中間表的關係,會自動刪除
51 EntityManagerFactory factory=Persistence.createEntityManagerFactory("sample");
52 EntityManager em=factory.createEntityManager();
53 em.getTransaction().begin();
54 Student student=em.find(Student.class, 1);
55 em.remove(student);
56 em.getTransaction().commit();
57 em.close();
58 factory.close();
59 }
雙向多對多關係是一種對等關係,既然是對等關係,也就是說我們可以人為決定誰是關係維護端,實際中根據業務需要自行選擇。