hibernate关联映射之一对多&多对一

package loaderman.b_one2Many;

import java.util.HashSet;
import java.util.Set;

public class Dept {

    private int deptId;
    private String deptName;
    // 【一对多】 部门对应的多个员工
    private Set<Employee> emps = new HashSet<Employee>();

    public int getDeptId() {
        return deptId;
    }
    public void setDeptId(int deptId) {
        this.deptId = deptId;
    }
    public String getDeptName() {
        return deptName;
    }
    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }
    public Set<Employee> getEmps() {
        return emps;
    }
    public void setEmps(Set<Employee> emps) {
        this.emps = emps;
    }

}
package loaderman.b_one2Many;

public class Employee {

    private int empId;
    private String empName;
    private double salary;
    // 【多对一】员工与部门
    private Dept dept;

    public int getEmpId() {
        return empId;
    }
    public void setEmpId(int empId) {
        this.empId = empId;
    }
    public String getEmpName() {
        return empName;
    }
    public void setEmpName(String empName) {
        this.empName = empName;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public Dept getDept() {
        return dept;
    }
    public void setDept(Dept dept) {
        this.dept = dept;
    }

}
package loaderman.b_one2Many;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;

public class App1_save {

    private static SessionFactory sf;
    static {
        sf = new Configuration()
                .configure()
                .addClass(Dept.class)
                .addClass(Employee.class)   // 测试时候使用
                .buildSessionFactory();
    }

    // 保存, 部门方 【一的一方法操作】
    @Test
    public void save() {

        Session session = sf.openSession();
        session.beginTransaction();

        // 部门对象
        Dept dept = new Dept();
        dept.setDeptName("应用开发部");
        // 员工对象
        Employee emp_zs = new Employee();
        emp_zs.setEmpName("张三");
        Employee emp_ls = new Employee();
        emp_ls.setEmpName("李四");
        // 关系
        dept.getEmps().add(emp_zs);
        dept.getEmps().add(emp_ls);

        // 保存
        session.save(emp_zs);
        session.save(emp_ls);
        session.save(dept); // 保存部门,部门下所有的员工

        session.getTransaction().commit();
        session.close();
        /*
         *  结果
         *  Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
            Hibernate: insert into t_employee (empName, salary, dept_id) values (?, ?, ?)
            Hibernate: insert into t_dept (deptName) values (?)
            Hibernate: update t_employee set deptId=? where empId=?    维护员工引用的部门的id
            Hibernate: update t_employee set deptId=? where empId=?
         */
    }
    // 【推荐】 保存, 部员方 【多的一方法操作】
    @Test
    public void save2() {

        Session session = sf.openSession();
        session.beginTransaction();

        // 部门对象
        Dept dept = new Dept();
        dept.setDeptName("综合部");
        // 员工对象
        Employee emp_zs = new Employee();
        emp_zs.setEmpName("张三");
        Employee emp_ls = new Employee();
        emp_ls.setEmpName("李四");
        // 关系
        emp_zs.setDept(dept);
        emp_ls.setDept(dept);

        // 保存
        session.save(dept); // 先保存一的方法
        session.save(emp_zs);
        session.save(emp_ls);// 再保存多的一方,关系会自动维护(映射配置完)

        session.getTransaction().commit();
        session.close();
        /*
         *  结果
         *  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 (?, ?, ?)
            少生成2条update  sql
         */
    }

}
package loaderman.b_one2Many;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;

public class App2_get {

    private static SessionFactory sf;
    static {
        sf = new Configuration()
                .configure()
                .addClass(Dept.class)
                .addClass(Employee.class)   // 测试时候使用
                .buildSessionFactory();
    }

    @Test
    public void get() {

        Session session = sf.openSession();
        session.beginTransaction();

        // 通过部门方,获取另外一方
//        Dept dept = (Dept) session.get(Dept.class, 1);
//        System.out.println(dept.getDeptName());
//        System.out.println(dept.getEmps());// 懒加载

        // 通过员工房,获取另外一方
        Employee emp = (Employee) session.get(Employee.class, 1);
        System.out.println(emp.getEmpName());
        System.out.println(emp.getDept().getDeptName());

        session.getTransaction().commit();
        session.close();
    }

}
package loaderman.b_one2Many;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;

public class App3_inverse {

    private static SessionFactory sf;
    static {
        sf = new Configuration()
                .configure()
                .addClass(Dept.class)
                .addClass(Employee.class)   // 测试时候使用
                .buildSessionFactory();
    }

    // 1. 保存数据
    @Test
    public void save() {

        Session session = sf.openSession();
        session.beginTransaction();

        // 部门对象
        Dept dept = new Dept();
        dept.setDeptName("应用开发部");
        // 员工对象
        Employee emp_zs = new Employee();
        emp_zs.setEmpName("张三");
        Employee emp_ls = new Employee();
        emp_ls.setEmpName("李四");
        // 关系
        dept.getEmps().add(emp_zs);
        dept.getEmps().add(emp_ls);  // inverse=true,  不会设置关联。
        //                 此时的关联应该通过员工方维护。

        // 保存
        session.save(emp_zs);
        session.save(emp_ls);
        session.save(dept); // 保存部门,部门下所有的员工

        session.getTransaction().commit();
        session.close();
    }

    //2. 是否设置inverse,对获取数据的影响?   无.
    @Test
    public void get() {
        Session session = sf.openSession();
        session.beginTransaction();

        Dept dept = (Dept) session.get(Dept.class, 1);
        System.out.println(dept.getDeptName());
        System.out.println(dept.getEmps());

        session.getTransaction().commit();
        session.close();
    }

    // 3. 是否设置inverse,对解除关联关系影响?
    // inverse=false,  可以解除关联
    // inverse=true,  当前方(部门)没有控制权,不能解除关联关系(不会生成update语句,也不会报错)
    //
    @Test
    public void removeRelation() {
        Session session = sf.openSession();
        session.beginTransaction();

        // 获取部门
        Dept dept = (Dept) session.get(Dept.class, 2);
        // 解除关系
        dept.getEmps().clear();

        session.getTransaction().commit();
        session.close();
    }

    //3. 是否设置inverse属性,在删除数据中对关联关系的影响?
    // inverse=false, 有控制权, 可以删除。先清空外键引用,再删除数据。
    // inverse=true,  没有控制权: 如果删除的记录有被外键引用,会报错,违反主外键引用约束!
    //                             如果删除的记录没有被引用,可以直接删除。
    @Test
    public void deleteData() {
        Session session = sf.openSession();
        session.beginTransaction();

        // 查询部门
        Dept dept = (Dept) session.get(Dept.class, 8);
        session.delete(dept);

        session.getTransaction().commit();
        session.close();
    }

    @Test
    public void bak() {
        Session session = sf.openSession();
        session.beginTransaction();

        session.getTransaction().commit();
        session.close();
    }

}
package loaderman.b_one2Many;

import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;

public class App4_cascade {

    private static SessionFactory sf;
    static {
        sf = new Configuration()
                .configure()
                .addClass(Dept.class)
                .addClass(Employee.class)   // 测试时候使用
                .buildSessionFactory();
    }

    // 级联保存
    @Test
    public void save() {

        Session session = sf.openSession();
        session.beginTransaction();

        // 部门对象
        Dept dept = new Dept();
        dept.setDeptName("财务部");
        // 员工对象
        Employee emp_zs = new Employee();
        emp_zs.setEmpName("张三");
        Employee emp_ls = new Employee();
        emp_ls.setEmpName("李四");
        // 关系
        dept.getEmps().add(emp_zs);
        dept.getEmps().add(emp_ls);

        // 保存
//        session.save(emp_zs);
//        session.save(emp_ls);
        session.save(dept); // 需要设置级联保存; 保存部门,部门下所有的员工

        session.getTransaction().commit();
        session.close();
    }

    // 级联删除
    @Test
    public void delete() {
        Session session = sf.openSession();
        session.beginTransaction();

        Dept dept = (Dept) session.get(Dept.class,7);
        session.delete(dept); // 级联删除

        session.getTransaction().commit();
        session.close();
    }

    @Test
    public void bak() {
        Session session = sf.openSession();
        session.beginTransaction();

        session.getTransaction().commit();
        session.close();
    }

}
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="loaderman.b_one2Many">

    <class name="Dept" table="t_dept">
        <id name="deptId">
            <generator class="native"></generator>
        </id>
        <property name="deptName" length="20"></property>

        <!--
            一对多关联映射配置  (通过部门管理到员工)
            Dept 映射关键点:
            1.  指定 映射的集合属性: "emps"
            2.  集合属性对应的集合表: "t_employee"
            3.  集合表的外键字段   "t_employee. dept_id"
            4.  集合元素的类型

            inverse=false  set集合映射的默认值; 表示有控制权
         -->
         <set name="emps" cascade="save-update,delete" table="t_employee" inverse="true">   <!-- table="t_employee" -->
              <key column="dept_id"></key>
              <one-to-many class="Employee"/>
         </set>

    </class>

</hibernate-mapping>
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="loaderman.b_one2Many">

    <class name="Employee" table="t_employee">
        <id name="empId">
            <generator class="native"></generator>
        </id>
        <property name="empName" length="20"></property>
        <property name="salary" type="double"></property>

        <!--
            多对一映射配置
            Employee 映射关键点:
            1.  映射的部门属性  :  dept
            2.  映射的部门属性,对应的外键字段: dept_id
            3.  部门的类型
         -->
         <many-to-one name="dept" column="dept_id" class="Dept"></many-to-one>

    </class>

</hibernate-mapping>

原文地址:https://www.cnblogs.com/loaderman/p/10037442.html

时间: 2024-10-12 12:46:04

hibernate关联映射之一对多&多对一的相关文章

第六章 Hibernate关联映射

第六章 hibernate关联映射一.本章知识点分为2部分:1.关联关系:单向多对一关联关系,双向一对多关联关系(含一对多关联关系),多对多关联关系2.延迟加载:类级别加载策略,一对多加载策略,多对一加载策略二.关联关系1.单向多对一关联关系1.1.概念(什么是单向多对一关联关系,举例说明)  以部门(Dept).Emp(员工)为例: 从员工角度看部门,是多个员工都在一个部门,这就叫单向 如部门编号为20的部门下可以有n个员工(如scott账户下emp表 empno 为7369,7566,778

Hibernate关联映射(单项多对一和一对多、双向一对多)

最近总是接触着新的知识点来扩展自己的知识面:不停的让自己在原地接触天空的感觉真的很美好!!!革命没有成功,程序员的我们怎么能不努力呢...... 一.用员工和部门来剖析关联映射的原理. 1)从这张截图可以看出我会站在员工的角度讲述:(单向关联) 关系:(多个员工对应一个部门)多对一的关系 意味:多个Emp对象只会引用一个Dept对象 方法:在Emp类中定义一个Dept类型属性,来引用所有关联的Dept对象 eg. 第一步建立两个实体类省略 第二步建立大配置 <?xml version='1.0'

hibernate关联映射

本文可作为北京尚学堂马士兵hibernate课程的学习笔记. hibernate的映射,主要分为一对一,一对多,多对一,多对多,同时还要单向与双向的区别. OK,不要纠结于名字,我们开始看例子. 一对一单向 老公是一个实体,老婆也是一个实体. 一个老公只有一个老婆,同时一个老婆也只有一个老公. 上面的关系就叫做一对一. 什么叫单向呢. 看代码: package com.bjsxt.hibernate; @Entity public class Husband { private int id;

Hibernate关联映射 映射文件的配置

一:多对一单向关联 首先我们必须创建两个实体类 例如:Dept类 public class Dept { private Integer deptNo; private String dName; private String loc; private Set<Employee> emps=new HashSet<Employee>(); Employee类 public class Employee { private Integer empno; private String

Hibernate关联映射关系

一.双向一对多关联映射关系:当类与类之间建立了关联,就可以方便的从一个对象导航到另一个或另一组与它关联的对象(一对多双向关联和多对一双向关联是完全一样的) 1.1创建实体类(Emp(员工),Dept(部门)) /* * 员工实体类 */public class Emp { private Integer empId; //员工编号 private String empName; //员工姓名 private Dept dept; //所处部门 //get(),set()方法省略 } /* * 部

Hibernate 关联映射

ORM(Object Relational Mapping)对象/关系映射 说到Hibernate的关联映射就必须要提一提ORM了.那么ORM是什么呢,其是一种持久化技术,他在对象模型和关系型数据库之间建立对象关系,通过操作JavaBean对象来完成对数据库的操作! 注意:ORM是概念化的并不是实际存在的,可以理解为其是一种编程思想,而Hibernate框架就是该思想的实现产品! 配置Po对象(和数据表绑定的持久化对象)的关联关系 从上面说到ORM可以在对象模型和数据库之间建立对应关系而在Hib

Hibernate关联映射(3) 2016-07-12

接上篇,开始一对多单向关联.由于多对一的单向关联已经在(1)中说过,就不再说了,主要思想就是一对一是使用了more-to-one多对一的特殊形式,利用unique="true"转换成特殊的一对一来使用. 说明:一对多仍然使用person和address的例子.在一对多单向关联的例子中,一个person可以有多个address,所以在person类中有一个set集合属性的成员变量,集合里面存的是address类型的变量. 一对多外键 单向关联 由于是一个person可以有多个addres

hibernate关联映射(一对多)

这篇博客将会给大家带来hibernate的关联映射的学习.在现实生活中,不仅只是一对一的映射关系,更多的是一对多,多对多等. 一对多单项关联映射 这里我以网盘为例,一个用户可以拥有多个文件,及用户和文件之间是一对多的关系. user实体类: public class Users { private int uid; private String uname; //用户上传的所有文件 // one方 可以获取 many方 private Set<UpFile> files = new HashS

hibernate关联映射【一对一主键】

从三个部分介绍Hibernate一对一主键关联映射. 1.基本介绍2.代码展示3.总结注意  1.基本介绍 一对一关联有两种情况: 单向一对一主键关联.双向一对一主键关联.一对一主键关联: 是指两个表之间通过主键形成一对一的映射,例如,每个公民只允许拥有一个身份证,公民与身份证就是一对一的关系,定义两张表,一张People表,一张IdCard表,People表的id既是该表的主键也是该表的外键,并且People的id也就是IdCard的id, 2.代码 单向一对一主键关联:people表的id既