多對多雙向關聯比較麻煩,一般添加第三個表變為兩個多對一進行處理,以學生和課程之間的關系為例,實體類和配置如下
Course
1 package domain;
2
3 import java.util.Set;
4
5 public class Course {
6
7 private int id;
8 private String name;
9
10 private Set<StudentCourse> studentCourses;
11
12 //get/set和構造省略,但實際不可省略
13
14 }
15
1 <?xml version="1.0"?>
2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
4 <hibernate-mapping>
5 <class name="domain.Course" table="COURSE">
6 <id name="id" type="int">
7 <column name="ID" />
8 <generator class="native" />
9 </id>
10 <property name="name" type="java.lang.String">
11 <column name="NAME" />
12 </property>
13 <set name="studentCourses" inverse="true" lazy="extra">
14 <key column="cid"/>
15 <one-to-many class="domain.StudentCourse" />
16 </set>
17 </class>
18 </hibernate-mapping>
19
Student
1 package domain;
2
3 import java.util.Set;
4
5 public class Student {
6
7 private int id;
8 private String name;
9
10 private Set<StudentCourse> studentCourses;
11
12 //get/set和構造省略,但實際不可省略
13
14 }
15
1 <?xml version="1.0"?>
2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
4 <hibernate-mapping>
5 <class name="domain.Student" table="STUDENT">
6 <id name="id" type="int">
7 <column name="ID" />
8 <generator class="native" />
9 </id>
10 <property name="name" type="java.lang.String">
11 <column name="NAME" />
12 </property>
13 <set name="studentCourses" inverse="true" lazy="extra">
14 <key column="sid"/>
15 <one-to-many class="domain.StudentCourse"/>
16 </set>
17 </class>
18 </hibernate-mapping>
19
1 package domain;
2
3 public class StudentCourse {
4
5 private int id;
6 private int point;
7
8 private Student student;
9 private Course course;
10 //get/set和構造省略,但實際不可省略
11
12 }
13
1 <?xml version="1.0"?>
2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
4 <hibernate-mapping>
5 <class name="domain.StudentCourse" table="STUDENTCOURSE">
6 <id name="id" type="int">
7 <column name="ID" />
8 <generator class="native" />
9 </id>
10 <property name="point" type="int">
11 <column name="POINT" />
12 </property>
13 <many-to-one column="sid" name="student" class="domain.Student"/>
14 <many-to-one column="cid" name="course" class="domain.Course"/>
15 </class>
16 </hibernate-mapping>
17
書寫測試代碼
1 package demo;
2
3 import org.hibernate.Session;
4 import org.junit.Test;
5
6 import domain.Course;
7 import domain.Student;
8 import domain.StudentCourse;
9 import util.HibernateUtil;
10
11 public class App
12 {
13
14 @Test
15 /**
16 * manyTomany中,需要添加第三個表來維護兩個提示之間的關系,但是一般來說,第三個表,還會添加其他的一些內容
17 * 就比如,學生和課程之間的關系,在關系表中還會添加成績這一個字段
18 */
19 public void addTest() {
20 Session session = null;
21 try {
22 session = HibernateUtil.openSession();
23 session.beginTransaction();
24
25 Student student = new Student();
26 student.setName("二愣子");
27 session.save(student);
28
29 Student student2 = new Student();
30 student2.setName("大棒槌");
31 session.save(student2);
32
33 Course course = new Course();
34 course.setName("高達駕駛技術");
35 session.save(course);
36
37 Course course2 = new Course();
38 course2.setName("外星語言");
39 session.save(course2);
40
41 StudentCourse studentCourse = new StudentCourse();
42 studentCourse.setPoint(99);
43 studentCourse.setStudent(student);
44 studentCourse.setCourse(course);
45 session.save(studentCourse);
46
47 session.getTransaction().commit();
48 } catch (Exception e) {
49 if (session != null) {
50 session.getTransaction().rollback();
51 }
52 } finally {
53 if (session != null) {
54 session.close();
55 }
56 }
57 }
58
59 @Test
60 /**
61 * 最佳實踐:多對多雙向關聯比較麻煩,不僅添加時需要很多操作,而且查詢的時候由于延遲加載會發很多sql
62 * 實際應用中可以考慮直接使用原生sql查詢
63 */
64 public void addTest02() {
65 Session session = null;
66 try {
67 session = HibernateUtil.openSession();
68 session.beginTransaction();
69
70 Student student = (Student) session.load(Student.class, 1);
71 System.out.println(student.getName());
72
73 for (StudentCourse s : student.getStudentCourses()) {
74 System.out.println(s.getCourse().getName() + ":" + s.getPoint());
75 }
76
77 session.getTransaction().commit();
78 } catch (Exception e) {
79 if (session != null) {
80 session.getTransaction().rollback();
81 }
82 } finally {
83 if (session != null) {
84 session.close();
85 }
86 }
87 }
88 }
89