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查询)还是直接选取(select查询) -->
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