一、 POJO 类 及 xxx.hbm.xml 配置文件
public class Student {
private int id;
private String sname;
private Teacher teacher; //老师对象属性
....
}
public class Teacher {
private Integer id;
private String tname;
//学生对象集合属性
private Set<Student> student = new HashSet<Student>();
...
}
从老师的角度:双向n(学生)many-to-one , 和单向没变化。映射用个 package 属性,方便管理包名
<hibernate-mapping package="cn.jq.hibernate5.model">
<class name="Student" table="T_STUDENT">
<id name="id" type="int">
<column name="id" />
<generator class="native" />
</id>
<property name="sname" type="java.lang.String">
<column name="s_name" />
</property>
<many-to-one name="teacher" class="Teacher">
<column name="teacher_id" />
</many-to-one>
</class>
</hibernate-mapping>
从老师的角度:双向1(老师) one-to-many 映射 ,映射用个 package 属性,方便管理包名
<hibernate-mapping package="cn.jq.hibernate5.model">
<class name="Teacher" table="T_TEACHER">
<id name="id" type="java.lang.Integer">
<column name="id" />
<generator class="native" />
</id>
<property name="tname" type="java.lang.String">
<column name="t_name" />
</property>
<!--
name: 为Teacher(1)类 这端的属性名
table: 为 Teacher(1)类 这端属性 所在的表名
key(column): 与Student(多)表外键名一致
calss: 为Student(多)类 这端的 全限定类名(此处使用了package属性)
-->
<set name="student" table="T_STUDENT" inverse="true" order-by="id desc">
<key>
<column name="teacher_id"></column>
</key>
<one-to-many class="Student"/>
</set>
</class>
</hibernate-mapping>
inverse=“true”: 它的作用是指定双向多对一的映射中, 由那一边来维护关系。
inverse="false" (默认值是)主动维护
inverse="true" 放弃维护
无 两端都维护
在双向1对n中,推荐 inverse="true",将 1 端放弃维护, 让 n 端主动维护。
cascade="delete", 表示执行级联删除, 开发时不建议设置,建议根据需求手工方式来处理
order-by="类属性名 asc/desc ": 设置查询出来的数据的排序
@Test
public void test() {
Teacher teacher = session.get(Teacher.class, 1);
Set<Student> student = teacher.getStudent();
for (Student stu : student) {
System.out.println(stu);
}
}
----降序----
Student [id=2, sname=学生2, teacher=Teacher [id=1, tname=老师1]]
Student [id=1, sname=学生1, teacher=Teacher [id=1, tname=老师1]]
图简单明了
二、 junit 测试
建表 sql : 和单向一样
1、 新增:推荐先插入一(1)的这端, 效率高!
@Test
public void test() {
Teacher teacher = new Teacher("老师1");
Student student1 = new Student();
student1.setSname("学生1");
Student student2 = new Student();
student2.setSname("学生2");
//建立双向多对一关联关系
student1.setTeacher(teacher);
student2.setTeacher(teacher);
teacher.getStudent().add(student1);
teacher.getStudent().add(student2);
session.save(teacher);
session.save(student1);
session.save(student2);
}
2. 删除:
结论: 删除 Student (多) 这端数据,可正常删除,Teacher(1) 这端数据 没影响 。
不使用 cascade="delete"时, 删除 Teacher (1) 这端数据, 会出错, 因为受到 外键约束。
3. 修改: 正常操作, 没问题
4. 查询:
结论: 默认情况下, 查询多(n)这端对象, 只要没使用到关联的对象, 不会发起关联的对象的查询!
因为使用的懒加载, 所以在使用关联对象之前关闭session, 必然发生赖加载异常!