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.inverse属性

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

  • 保存数据 有影响

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

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

    inverse=false,  可以解除关联

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

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

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

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

6.cascade属性

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

none                 不级联操作, 默认值

save-update     级联保存或更新

delete               级联删除

all                     级联保存、更新、删除

时间: 2024-10-17 13:23:11

Hibernate中的一对多与多对一映射的相关文章

Hibernate中的一对多、多对多映射

一.一对多映射  如快递网点(ExpSite)与快递员(Deliver)的关系,即为一对多关系,一个快递网点有多个快递员,他们的关系如下图所示. 在一对多中,外键在多的一方 (1)在多的一方配置外键 Deliver表为多方,在Deliver实体类中放一个ExpSite方的引用做属性(外键),即所属网点ExpSiteId; Deliver实体类配置文件: <many-to-one name="ExpSiteId" class="ExpSite表所在的包名+ExpSite表

Hibernate之实现一对多、多对一映射关联关系

一对多.多对一这种关系在现实生活中很多,例如部门与员工的关系,学校里班级与学生的关系... 那么在具体的系统实现中如果i实现这种关联关系呢?这里以部门和员工的关系为例. 部门实体类 package test.hibernate.hbmOneToMany; import java.util.HashSet; import java.util.Set; public class Department { private Integer id; private String name; private

Hibernate的集合一对多与多对一

需求:   部门与员工 一个部门有多个员工;       [一对多] 多个员工,属于一个部门    [多对一] 1.javaBean --Dept.java package com.gqx.onetomany; import java.util.HashSet; import java.util.Set; public class Dept { private int deptId; private String deptName; //部门对应的多个员工 (一对多) private Set<E

Hibernate实现双向一对多,多对一

人与电话号码是一对多 ,多对一的关系 @Entity @Table(name="tb_person") public class Person { @Id @GeneratedValue(strategy = GenerationType.AUTO) private int id; private String name; @OneToMany(mappedBy = "person") /*在双向一对多关系中 将控制权交给“多”方 */ private List&l

Hibernate之关于一对多,多对一双向关联映射

[Hibernate]之关于一对多,多对一双向关联映射 由于一对多,和多对一的双向关联映射基本上一样,所以这里就一起写下来! Annotations配置 @Entity @Table(name="t_group") publicclass Group { private Integer id; private String name; private Set<Person> persons=newHashSet<Person>();//set不允许重复,最适合数

Mybatis(四) 高级映射,一对一,一对多,多对多映射

天气甚好,怎能不学习? 一.单向和双向 包括一对一,一对多,多对多这三种情况,但是每一种又分为单向和双向,在hibernate中我们就详细解析过这单向和双向是啥意思,在这里,在重复一遍,就拿一对多这种关系来讲,比如有员工和部门,一个部门中有多个员工,从部门方看,是一对多关系,而多名员工属于一个部门,是多对一关系,那么如果我们的业务需求只需要通过部门查找到所有的员工,那么我们就只需要进行单向一对多的映射,如果我们需要通过员工来查询出对应的部门,那么我们就需要进行单向多对一的映射,而如果我们这两个业

三大框架 之 Hibernate查询(一对多、多对多、查询关系)

目录 一对多 表之间关系 表之间关系建表原则 一对多关系配置 建立表 建立ORM 添加配置文件 添加核心配置文件 引入工具类 编写测试类 级联操作 什么是级联 级联分类 级联是有方向性 级联保存或更新 级联删除 在双向级联的过程当中,会产生一些多余的sql语句 lazy懒加载(默认值是proxy,不自动获取外键对象) 级联保存或更新(解决 瞬时对象异常,只保存一边) 多对多 多对多关系配置 建立表 建立ORM 添加配置文件 在核心配置文件当中添加两个新配置 编写测试类 多对多的操作 查询方式 O

Hibernate 一对一、一对多、多对多注解属性的总结

mappedBy: 所填内容必为本类在另一方的字段名. 表示:本类放弃控制关联关系,所有对关联关系的控制,如:建立.解除与另一方的关系,都由对方控制,本类不管.举个例子: Teacher和Student之间是多对多关联关系,在Student端的teachers字段的@ManyToMany注解里面,配置属性mappedBy = "students".表示:学生没有资格控制与老师的关联关系(如:建立关系.删除关系),只有老师才有资格控制关联关系.学生不能说:"我们两做朋友吧&qu

hibernate之初学一对多和多对一配置及使用

按查询及存取速率来说的一对多用的相对多对一少一些,这里只写主要配置文件的代码 首先是hibernate的配置文件 <!DOCTYPE hibernate-configuration PUBLIC "-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-co