hibernate中,配置表關系可以說是比較繞人的,先記一個最簡單的配置
多對一單向關聯,配置學生和老師之間的多對一關系
實體類和配置
Student
1 package domain;
2
3 public class Student {
4
5 private int id;
6 private String name;
7 private String grade;
8 private Teacher teacher;
9 //get/set和構造省略,但是不可不寫
10
11 }
12
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
5 <hibernate-mapping>
6 <class name="domain.Student" table="STUDENT">
7 <id name="id" type="int">
8 <column name="ID" />
9 <generator class="native" />
10 </id>
11 <property name="name" type="java.lang.String">
12 <column name="NAME" />
13 </property>
14 <property name="grade" type="java.lang.String">
15 <column name="GRADE" />
16 </property>
17 <!-- fetch意為抓取策略,在級聯查詢的時候,當取得關聯對象的時候,是關聯選取(join查詢)還是直接選?。╯elect查詢) -->
18 <!-- cascade級聯屬性,表示對關聯關系的維護,開啟之后,會自動完成對象間的關聯。
19 有三個選項,delete,update和all,表示當對象進行刪除,更新時,是否對關聯對象進行相應操作。
20 一般情況下該選項不啟用,就算是用,也是極有可能在一的一方進行刪除的時候使用 -->
21 <many-to-one name="teacher" class="domain.Teacher" fetch="join">
22 <column name="TEACHER_ID" />
23 </many-to-one>
24 </class>
25 </hibernate-mapping>
26
Teacher
1 package domain;
2
3 public class Teacher {
4
5 private int id;
6 private String name;
7 private String course;
8 //get/set和構造省略,但是不可不寫
9
10 }
11
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
5 <hibernate-mapping>
6 <class name="domain.Teacher" table="TEACHER">
7 <id name="id" type="int">
8 <column name="ID" />
9 <generator class="native" />
10 </id>
11 <property name="name" type="java.lang.String">
12 <column name="NAME" />
13 </property>
14 <property name="course" type="java.lang.String">
15 <column name="COURSE" />
16 </property>
17 </class>
18 </hibernate-mapping>
19
配置至此基本完成,現在書寫測試類
1 package demo;
2
3 import org.hibernate.Session;
4 import org.junit.Test;
5
6 import domain.Student;
7 import domain.Teacher;
8 import util.HibernateUtil;
9
10 public class App
11 {
12 @Test
13 /**
14 * ManyToOne中,需要先添加一的一方,再添加多的一方,這樣效率高
15 * 在案例中,先保存一個teacher對象,在保存兩個學生對象,這樣只會使用三個insert語句完成操作
16 */
17 public void addTest() {
18 Session session = null;
19 try {
20 session = HibernateUtil.openSession();
21 session.beginTransaction();
22
23 Teacher teacher = new Teacher();
24 teacher.setName("張老師");
25 teacher.setCourse("物理");
26 session.save(teacher);
27
28 Student stu1 = new Student();
29 stu1.setName("小明");
30 stu1.setGrade("一");
31 stu1.setTeacher(teacher);
32 session.save(stu1);
33
34 Student stu2 = new Student();
35 stu2.setName("小紅");
36 stu2.setGrade("二");
37 stu2.setTeacher(teacher);
38 session.save(stu2);
39
40 session.getTransaction().commit();
41
42 } catch (Exception e) {
43 if (session != null) {
44 session.getTransaction().rollback();
45 }
46 } finally{
47 if (session != null) {
48 session.close();
49 }
50 }
51 }
52
53 @Test
54 /**
55 * 下個案例中,先添加了多的一方,再添加一的一方,這樣會導致冗余的sql語句,會多出兩個Updatesql
56 * 所以最佳實踐就是:添加的時候先添加一的一方,然后再添加多的一方
57 */
58 public void addTest2() {
59 Session session = null;
60 try {
61 session = HibernateUtil.openSession();
62 session.beginTransaction();
63
64 Student stu1 = new Student();
65 stu1.setName("小明");
66 stu1.setGrade("一");
67 session.save(stu1);
68
69 Student stu2 = new Student();
70 stu2.setName("小紅");
71 stu2.setGrade("二");
72 session.save(stu2);
73
74 Teacher teacher = new Teacher();
75 teacher.setName("張老師");
76 teacher.setCourse("物理");
77 session.save(teacher);
78
79 stu1.setTeacher(teacher);
80 stu2.setTeacher(teacher);
81
82 session.getTransaction().commit();
83
84 } catch (Exception e) {
85 if (session != null) {
86 session.getTransaction().rollback();
87 }
88 } finally{
89 if (session != null) {
90 session.close();
91 }
92 }
93 }
94
95 @Test
96 /**
97 * 關于延遲加載,多對一關系中,若取得的多的一方的對象,沒有進一步取得一的一方的對象,則不會立刻查詢
98 * 除非需要進一步取得一的一方的內容
99 */
100 public void addTest3() {
101 Session session = null;
102 try {
103 session = HibernateUtil.openSession();
104 session.beginTransaction();
105
106 Student student = (Student) session.load(Student.class, 10);
107 System.err.println(student.getName());
108 System.err.println(student.getTeacher().getName());
109
110 session.getTransaction().commit();
111
112 } catch (Exception e) {
113 if (session != null) {
114 session.getTransaction().rollback();
115 }
116 } finally{
117 if (session != null) {
118 session.close();
119 }
120 }
121 }
122
123 @Test
124 /**
125 * 級聯的設置,若在配置文件中添加了cascade,則會自動生成一個外鍵對象并保存
126 * 注意:cascade級聯操作,不要在多的一方添加級聯,這樣在刪除的時候會導致一些異常,
127 * 要添加也是在一的一方添加,而且不是特殊要求的情況下,不要添加級聯
128 */
129 public void addTest4() {
130 Session session = null;
131 try {
132 session = HibernateUtil.openSession();
133 session.beginTransaction();
134
135 Teacher teacher = new Teacher();
136 teacher.setName("白老師");
137 teacher.setCourse("物理");
138 //session.save(teacher);
139 //此處沒有保存Teacher對象,直接保存不會成功
140
141 Student stu1 = new Student();
142 stu1.setName("小黑");
143 stu1.setGrade("一");
144 stu1.setTeacher(teacher);
145 session.save(stu1);
146
147 session.getTransaction().commit();
148
149 } catch (Exception e) {
150 if (session != null) {
151 session.getTransaction().rollback();
152 }
153 } finally{
154 if (session != null) {
155 session.close();
156 }
157 }
158 }
159 }
160