zoukankan      html  css  js  c++  java
  • Hibernate中的一对多与多对一映射

    1.需求

      一个部门有多个员工;         【一对多】

      多个员工,属于一个部门    【多对一】

    2.实体Bean设计

      Dept:

    public class Dept {
        private int depId;
        private String depName;
        private Set<Employee> emps = new HashSet<Employee>();
        set...
        get...      
    }

      Employee:

    public class Employee {
        private int empId;
        private String empName;
        private double salary;
        private Dept dept;
        set...
        get...
    }

    3.配置映射文件

      Dept.hbm.xml

    <?xml version="1.0" encoding="utf-8" ?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="com.juaner.hibernate.department">
        <class name="Dept" table="t_dept">
            <!--主键-->
            <id name="depId">
                <generator class="native"/>
            </id>
            <property name="depName" column="deptName" type="string"/>
            <!--一对多关联映射的配置-->
            <set name="emps" table="t_employee" >
                <!--外键字段-->
                <key column="dept_id"></key>
                <!--一对多关系-->
                <one-to-many class="Employee"/>
            </set>
        </class>
    
    </hibernate-mapping>

      Employee.hbm.xml

    <?xml version="1.0" encoding="utf-8" ?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping package="com.juaner.hibernate.department">
        <class name="Employee" table="t_employee">
            <!--主键-->
            <id name="empId" column="empId">
                <generator class="native"/>
            </id>
            <property name="empName" column="empName" type="string"/>
            <property name="salary" column="salary"/>
            <!--多对一映射-->
            <many-to-one name="dept" column="dept_id" class="Dept"></many-to-one>
        </class>
    
    </hibernate-mapping>

    4.保存数据

    • 使用“一”的一方来设置关联
        @Test
        public void test1(){
            Session session = sf.openSession();
            session.beginTransaction();
    
            //部门对象
            Dept dept = new Dept();
            dept.setDepName("开发部");
            //员工对象
            Employee employee = new Employee();
            employee.setEmpName("张三");
            employee.setSalary(1000);
            Employee employee2 = new Employee();
            employee2.setEmpName("李四");
            employee2.setSalary(2000);
    
            dept.getEmps().add(employee);
            dept.getEmps().add(employee2);
    
            session.save(dept);
            session.save(employee);
            session.save(employee2);
    
            session.getTransaction().commit();
            session.close();
        }

      此时会执行5条sql语句,其中最后两条update语句用来设置关联:

            Hibernate: insert into t_dept (deptName) values (?)
            Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
            Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
            Hibernate: update t_employee set dept_id=? where empId=?
            Hibernate: update t_employee set dept_id=? where empId=?
    • 使用“多”的一方来设置关联
        @Test
        public void test2(){
            Session session = sf.openSession();
            session.beginTransaction();
    
            //部门对象
            Dept dept = new Dept();
            dept.setDepName("人事部");
            //员工对象
            Employee employee = new Employee();
            employee.setEmpName("张三");
            employee.setSalary(1000);
            Employee employee2 = new Employee();
            employee2.setEmpName("李四");
            employee2.setSalary(2000);
    
            employee.setDept(dept);
            employee2.setDept(dept);
            //先保存一的一方,再保存多的一方,关系会自动维护,减少不必要的语句
            session.save(dept);
            session.save(employee);
            session.save(employee2);
    
            session.getTransaction().commit();
            session.close();
    
        }

      此时只执行三条sql语句:

    Hibernate: insert into t_dept (deptName) values (?)
    Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
    Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)

    5.结果

      t_dept表:

      

      t_employee表:

      

    6.inverse属性

      inverse属性用来设置是否控制反转。在一对多的映射中,只能在“一”的一方配置,默认值为false,即“一”的一方掌握控制权。inverse的值对数据的影响如下:

    • 保存数据 有影响

        如果设置控制反转,即inverse=true, 然后通过部门方维护关联关系。在保存部门的时候,同时保存员工, 数据会保存,但关联关系不会维护。即外键字段为NULL

    • 获取数据 无影响
    • 解除关联关系 有影响

        inverse=false,  可以解除关联

        inverse=true,  当前方没有控制权,不能解除关联关系(不会生成update语句,也不会报错)

    • 删除数据对关联关系 有影响

                inverse=false, 有控制权, 可以删除。先清空外键引用,再删除数据

                inverse=true,  没有控制权: 如果删除的记录有被外键引用,会报错,违反主外键引用约束!  如果删除的记录没有被引用,可以直接删除

    7.cascade属性

      cascade属性用来设置级联方式,它有4个值:

    none                 不级联操作, 默认值

    save-update     级联保存或更新

    delete               级联删除

    all                     级联保存、更新、删除

  • 相关阅读:
    MYSQL数据库常用语句
    node.js(http协议)
    web 后端规范与思想
    linux系统下开启一个简单的web服务
    linux基础学习之软件安装以及常用命令(三)
    Vue如何使用动态刷新Echarts组件
    linux基础学习之软件安装以及常用命令
    linux基础学习
    浅谈FIle协议与Http协议及区别
    vueJs的简单入门以及基础语法
  • 原文地址:https://www.cnblogs.com/juaner767/p/5564803.html
Copyright © 2011-2022 走看看