更多Hibernate在框架开发
1 一对多(部门对员工)
1.0 确定一对多中的关系
部门:一,主表,
员工:多,从表,添加部门外键
注意: 部门需要知道有多少员工,员工需要知道自己属于哪个部门,这是一个双向关联的关系,在实体类和映射配置中,都是双向的关联。而在其他项目中,或许只存在单向关联的一对多关系。
1.1 编写实体类
部门实体类包含员工实体类的集合引用 ; 员工实体类包含部门实体类的对象引用。
Class Staff
public class Staff {
private String StaId;
private String StaName ;
private Depart depart ;
.........
}
Class Depart
public class Depart {
private Integer depId ;
private String depName ;
private Set<Staff> staffs = new HashSet<Staff>();
............
}
1.2 编写映射配置文件与核心配置文件
Staff.hbm.xml
<hibernate-mapping package="cn.kmust.entity">
<class name="Staff" table="tb_staff">
.......................
<!--
many-to-one: 建立多对一的映射配置
name: 员工实体类中的部门对象属性
class: 指定部门对象属性对应的实体类
colum: 员工表中外键字段名称
cascade:级联样式表
save-update: 级联保存和更新
delete:级联删除
-->
<many-to-one name="depart" cascade="save-update" class="Depart" column="depId"></many-to-one>
</class>
</hibernate-mapping>
Depart.hbm.xml
<hibernate-mapping package="cn.kmust.entity">
<class name="Depart" table="tb_depart">
.....................
<!--
set:
name: 部门实体类中的员工对象属性
table: 员工表,可以省略
inverse:true表示让部门在执行操作时,放弃维护关联关系的权利。 一般都是让多的那一方放弃。
key: 映射外键字段
column: 一对多中的外键字段名
one-to-mang: 建立一对多映射配置
class: 指定员工对象属性所对应的实体类
cascade:级联样式表
save-update: 级联保存和更新
delete:级联删除
-->
<set name="staffs" table="tb_staff" cascade="save-update,delete" inverse="true">
<key column="depId"></key>
<one-to-many class="Staff"/>
</set>
</class>
</hibernate-mapping>
hibernate.cfg.xml
<mapping resource="cn/kmust/entity/Staff.hbm.xml"/>
<mapping resource="cn/kmust/entity/Depart.hbm.xml"/
1.3 测试:级联添加 +级联删除
/**
* 添加部门的同时,级联添加员工
* 在Depart映射配置文件中配置级联属性cascade="save-update"
*/
//创建: 一个部门,两个员工
Depart dep_lab110 = new Depart();
dep_lab110.setDepName("110实验室");
Staff staWXT = new Staff() ;
staWXT.setStaName("王晓婷");
Staff staZDK = new Staff();
staZDK.setStaName("张大科");
//建立双向关联
dep_lab110.getStaffs().add(staWXT) ;
dep_lab110.getStaffs().add(staZDK) ;
staWXT.setDepart(dep_lab110);
staZDK.setDepart(dep_lab110);
//添加部门
session.save(dep_lab110);
/**
* 添加员工的同时,级联添加部门
* 在Staff映射配置文件中配置级联属性cascade="save-update"
*/
//创建:一个员工,一个部门
Depart dep_lab220 = new Depart() ;
dep_lab220.setDepName("220实验室");
Staff staFCY = new Staff() ;
staFCY.setStaName("付成尧");
//建立双向关联
dep_lab220.getStaffs().add(staFCY) ;
staFCY.setDepart(dep_lab220);
//添加员工
session.save(staFCY);
/**
* 添加员工的同时,把员工加入已存在的部门
*/
Depart dep_lab = session.get(Depart.class,1);
Staff staZYQ = new Staff();
staZYQ.setStaName("赵玉强");
//员工关联已有的部门
staZYQ.setDepart(dep_lab);
session.save(staZYQ);
/**
* 把赵玉强从110实验室部门转移到220实验室部门
* 在Staff映射配置文件中添加cascade="save-update"
*/
Depart dep_lab220 = session.get(Depart.class,4);
Staff sta = session.get(Staff.class,"ff808181634d8db301634d8db5f50000") ;
//建立双向关联
dep_lab220.getStaffs().add(sta);
sta.setDepart(dep_lab220);
/**
* 删除部门的同时,级联删除部门下的所有员工
* 在Depart映射配置文件中添加cascade="delete"
* 提示:如果不是级联删除,则先把部门下的所有员工的部门外键置为null,然后再删除该部门
*/
Depart dep_lab = session.get(Depart.class,1) ;
session.delete(dep_lab);
2 多对多(学生对教师)
2.0 确定多对多中的关系
学生:多,添加教师外键
教师:多,添加学生外键
数据库中需要第三张表维护两个外键关系
提醒: 虽然数据库中需要第三张表,但实体类并不需要第三个。不过需要注意的是,如果第三张表除了两个外键字段之外还有其他字段,则需要第三个实体类,其余两个实体类需与第三个实体类建立一对多的关系,构成这两个实体类的多对多关系,如果商品、订单和订单项。
2.1 编写实体类
教师实体类包含学生实体类的集合引用 ; 学生实体类包含教师实体类的集合引用 ;
Class Teacher
public class Teacher {
private String teaId ;
private String teaName ;
private Set<Student> students = new HashSet<Student>() ;
.................
}
Class Student
public class Student {
private String stuId ;
private String stuName ;
private Set<Teacher> teachers = new HashSet<Teacher>() ;
.................
}
2.2 编写映射配置文件与核心配置文件
Student.hbm.xml
<hibernate-mapping package="cn.kmust.entity">
<class name="Student" table="tb_student">
...........................
<!--
set:
name : 学生实体类中的教师对象集合属性
table: 中间表的表名
key:
column: 学生在中间表中的外键字段名
many-to-many:
class: 教师对象集合属性所在的实体类
colum: 教师在中间表中的外键字段名
inverse:放弃对外键的维护
cascade: 级联
-->
<set name="teachers" table="tb_student_teacher" inverse="true" cascade="save-update">
<key column="stuId"></key>
<many-to-many class="Teacher" column="teaId" />
</set>
</class>
</hibernate-mapping>
Teacher.hbm.xml
<hibernate-mapping package="cn.kmust.entity">
.................................
<!--
set:
name : 教师实体类中的学生对象集合属性
table: 中间表的表名
key:
column: 教师在中间表中的外键字段名
many-to-many:
class: 学生对象集合属性所在的实体类
colum: 学生在中间表中的外键字段名
cascade: 级联
-->
<set name="students" table="tb_student_teacher" cascade="save-update">
<key column="teaId"></key>
<many-to-many class="Student" column="stuId"/>
</set>
</class>
</hibernate-mapping>
hibernate.cfg.xml
<mapping resource="cn/kmust/entity/Student.hbm.xml"/>
<mapping resource="cn/kmust/entity/Teacher.hbm.xml"/>
2.3 测试: 级联保存+级联删除
/**
* 添加学生的同时,级联添加该学生的所有老师
*/
//创建: 一个学生,两个老师
Student stu_ZYQ = new Student() ;
stu_ZYQ.setStuName("赵玉强");
Teacher tea_QQ = new Teacher();
tea_QQ.setTeaName("钱谦");
Teacher tea_CLL = new Teacher();
tea_CLL.setTeaName("常璐璐");
//建立双向关系
stu_ZYQ.getTeachers().add(tea_CLL);
stu_ZYQ.getTeachers().add(tea_QQ);
tea_CLL.getStudents().add(stu_ZYQ);
tea_QQ.getStudents().add(stu_ZYQ);
session.save(stu_ZYQ);
提示: 实际项目中,禁用多对多的级联删除