Hibernate②一(多)对多的映射配置与级联操作

更多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);

提示: 实际项目中,禁用多对多的级联删除

猜你喜欢

转载自blog.csdn.net/g425680992/article/details/80291019