Hibernate映射解析之关联映射详解

Hibernate中的关联映射

关联关系

平时开发中,类与类之间最普遍的的关系就是关联关系,而且关联是有方向的。
以部门(Dept)和员工(Employee)为例:一个部门下有多个员工,而一个员工只能属于一个部门。

从Employee到Dept的关联就是 多对一 关联。 这就说明 每个Employee对象只会引用一个Dept对象,因此在Employee类中应该定义一个Dept类型的属性,来引用所关联的Dept对象。

从Dept到Employee的关联就是 一对多 关联。这就说明 每个Dept对象会引用一组Employee对象,因此应该在Employee类中定义一个集合类型的属性,来引用所有关联的Employee对象。

如果仅有从Employee到Dept的关联或者仅有从Dept到Employee的关联,就称为单向关联。
如果同时包含两种关联,就是双向关联。

单向关联

双向关联

配置多对一的关联关系

  1. 以员工和部门为例,配置 员工到部门的单向多对一关联
  2. 在Employee类中定义Dept类型的属性 dept;

配置文件中配置 使用'many-to-one'进行配置

private Integer id;
private String name;
private Integer age;
private Integer sex;
private Dept dept; //引用所属的部门

映射文件

<many-to-one name="dept" column="dept" class="com.ytzl.demo.entity.Dept" cascade="save-update"></many-to-one>
  1. name :属性名 这里就是 Employee中的dept
  2. column:外键字段 ,这里就是Employee表里的dept字段
  3. class :dept属性对应的类型 ,这里是 Dept类
  4. cascade:级联操作 这里是 保存和修改

配置一对多的关联关系

以员工和部门为例 ,从部门到员工的关联就是 一对多的关联

  1. 在Dept类中增加集合属性用来保存所引用的员工对象
  2. 在映射文件中配置 set

修改类属性

private Integer id;
private String name;
private Set<Employee> employees = new HashSet<>(); //用来保存员工引用

修改映射文件

<!-- 配置一对多的关联 -->
<set name="employees"> <!-- name 对应的属性名 就是集合的名字 -->
 <key column="dept"></key> <!-- 对应的是 employee表的外键字段名 -->
 <one-to-many class="com.ytzl.demo.entity.Employee"/> <!-- 关联的类 这里是 员工类 -->
</set>
  1. name :属性名 ,集合属性的名字
  2. key元素:column 属性 设定与所关联的持久化类对应的表的外键,这里是employee表的dept外键字段名
  3. one-to-many :class属性指定关联的持久化类 这里对应的是员工类

cascade 属性 关联操作

用于指定如何操作与当前对象关联的其他对象

可选值:

  1. none :默认值 ;不关联其他的对象
  2. save-update 当通过Session执行 save() ,update()saveOrUpdate()方法的时候级联更新或者保存所关联的对象
  3. delete :当通过session的delete()删除当前对象时,会级联 删除关联对象;
  4. all :包含 delete,save-update的行为

inverse属性 反转属性

在hibernate中,'inverse'属性指定了关联关系中的方向。

关联关系中,'inverse=”false”‘的为主动方,由主动方负责维护关联关系。

order-by属性 指定集合内元素的排序顺序

这里以员工和部门为例,部门内的员工要以年龄倒序的顺序排序,就可以通过设置 order-by属性

order-by="age desc"

多对多关联

以 员工和项目为例,一个员工可以参与到多个项目中,每个项目有多个员工的参于

  1. 配置 Project类 ,在类中添加集合属性 用于保存员工引用
  2. 配置Employee类,在类中添加集合睡醒,用于保存项目引用

往往多对多映射涉及到第三张表

Project类

private Integer id;
private String name;
private Set<Employee> employees = new HashSet<>();

配置Project映射类

<?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>
 <class name= "com.ytzl.demo.entity.Project" table ="project" dynamic-update="true">
 <id name="id" column="p_id" type="java.lang.Integer">
 <generator class="increment"></generator>
 </id>
 <property name="name" column="p_name" type="java.lang.String"></property>
 <set name="employees" table="emp_pro_relate" cascade="save-update">
 <key column="pro_id"></key>
 <many-to-many class="com.ytzl.demo.entity.Employee" column="emp_id"></many-to-many>
 </set>
 </class>
 </hibernate-mapping>
  1. set元素的table属性 对应第三张关联表
  2. key元素的column属性 对应project表在第三张表的外键
  3. many-to-many 元素 column对应关联对象在第三张表的外键

Employee类

private Integer id;
private String name;
private Integer age;
private Integer sex;
private Dept dept; //引用所属的部门
private Set<Project> projects = new HashSet<>(); //保存项目引用

Employee映射文件

<set name="projects" table="emp_pro_relate" inverse="true">
 <key column="emp_id"></key>
 <many-to-many class="com.ytzl.demo.entity.Project" column="pro_id"></many-to-many>
</set>

延迟加载

当hibernate从数据库中加载Dept对象时,如果同时加载所有关联的Employee对象,而我们仅仅需要Dept对象,那么这些关联的对象就白白浪费了许多内存空间,这时就有了延迟加载,如果实际需要用到Employee时再去加载。hibernate使用lazy属性指定延迟加载的查询策略

hibernate允许在对象-关系映射文件中配置加载策略

级别 说明
类级别 元素中lazy属性可选值为 true(延迟加载)和false(立即加载);默认值是true;
一对多关联级别 元素中lazy属性的可选值为 :true(延迟加载) ,extra(增强延迟加载),false(立即加载) 默认值为 true
多对一关联级别 元素中lazy属性的可选值为 :proxy(延迟加载),no-proxy(无代理延迟加载),和false(立即加载) ;默认值为 proxy

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对我们的支持。

(0)

相关推荐

  • Hibernate一对多关联双向关联代码实现分享

    1.创建实体类(Customer.java.Orders.java) 复制代码 代码如下: package wck.stu.vo.oneToMany_single; import java.util.HashSet;import java.util.Set; public class Customer {    private String id = ""; private String cName = ""; private String bank = "

  • 详解hibernate双向多对多关联映射XML与注解版

    双向多对多关联映射原理: 假设,一个员工可能有多个角色,一个角色可能有多个员工,从员工或角色的角度看,这就是多对多的关系,不管从哪一个角度看,都是多对多的联系.多对多关联映射关系一般采用中间表的形式来实现,即新增一种包含关联双方主键的表.实现多对多关联关系,在数据库底层通过添加中间表指定关联关系,而在hibernate框架在双方的实体中添加一个保存对方的集合,在双方的映射文件中使用<set>元素和<many-to-many>元素进行关联关系的配置. 如下图所示: (1)XML版 R

  • 深入解析Java的Hibernate框架中的一对一关联映射

    作为一个ORM框架,hibernate肯定也需要满足我们实现表与表之间进行关联的需要.hibernate在关联方法的实现很简单.下面我们先来看看一对一的做法:  不多说了,我们直接上代码:  两个实体类,TUser和TPassport: public class TUser implements Serializable{ private static final long serialVersionUID = 1L; private int id; private int age; priva

  • 举例讲解Java的Hibernate框架中的多对一和一对多映射

    多对一(Many-to-One)映射 多对一(many-to-one)关联是最常见的关联关系,其中一个对象可以与多个对象相关联.例如,一个相同的地址对象可以与多个雇员的对象相关联. 定义RDBMS表: 考虑一个情况,我们需要员工记录存储在EMPLOYEE表,将有以下结构: create table EMPLOYEE ( id INT NOT NULL auto_increment, first_name VARCHAR(20) default NULL, last_name VARCHAR(20

  • java Hibernate 一对多自身关联问题

    Hibernate 一对多自身关联问题 这个很难描述清楚,只能引用CSDN中我提问的帖子了: http://topic.csdn.net/u/20080711/16/7494bf10-48ca-4b2e-8a01-303e647f5516.html 方法,在表单中取得一个PO,然后session.save(po),如下: 程序代码             tx = session.beginTransaction();         session.save(catalog);        

  • hibernate一对多关联映射学习小结

    一对多关联映射  映射原理  一对多关联映射和多对一关联映射的映射原理是一致的,都是在多的一端加入一个外键,指向一的一端.关联关系都是由多端维护,只是在写映射时发生了变化. 多对一和一对多的区别 多对一和一对多的区别在于维护的关系不同: (1)多对一:多端维护一端的关系,在加载多端时,可以将一端加载上来. (2)一对多:一端维护多端的关系,在加载一端时,可以将多端加载上来. 分类 一对多单向关联映射 对象模型 从对象模型中,我们可以看出,Group持有User的一个引用.由于是单向关联,所以数据

  • Java的Hibernate框架中一对多的单向和双向关联映射

    一.一对多单向关联映射 一对多关系的对象模型在日常生活中也经常看到,就拿学生和班级来说,一个班级里有多个学生,所以班级和学生的关系是一对多的关系,映射到对象模型中,如下图: 对象模型说明了这种一对多的关系是由一的一端来维护的,那么映射成关系模型就是一个班级字段下面会有多个学生,这样就形成了一对多的关系,通过班级能够查询获得学生信息,对应的关系模型如下图: 1.基本配置 有了对象模型接下来就让它们映射为对应的关系代码,在进行关系映射时需要在一的一端添加<one-to-many>标签,另外还需要在

  • Hibernate映射解析之关联映射详解

    Hibernate中的关联映射 关联关系 平时开发中,类与类之间最普遍的的关系就是关联关系,而且关联是有方向的. 以部门(Dept)和员工(Employee)为例:一个部门下有多个员工,而一个员工只能属于一个部门. 从Employee到Dept的关联就是 多对一 关联. 这就说明 每个Employee对象只会引用一个Dept对象,因此在Employee类中应该定义一个Dept类型的属性,来引用所关联的Dept对象. 从Dept到Employee的关联就是 一对多 关联.这就说明 每个Dept对象

  • vmware 实现linux目录映射window本地目录图文详解

    ---恢复内容开始--- 背景: 1,使用lnmp环境 2,代码可以在windows上面写,直接映射到linux的lnmp环境下面 第一步: vmware 新建一个linux虚拟机 一路下一步到完成 第二步: 安装镜像(自己去下载一个linux的镜像) 然后确认 ,然后重新客户机 然后一路next(语言可以选中文) 直到这一步 给linux设置密码 然后一路next,确认所有修改 第三步: 进入linux系统配置网络 修改下图路径中的文档(onboot改成yes) 修改完保存 重启网络 第四步:

  • Java泛型映射不同的值类型详解及实例代码

    Java泛型映射不同的值类型详解 前言: 一般来说,开发人员偶尔会遇到这样的情形: 在一个特定容器中映射任意类型的值.然而Java 集合API只提供了参数化的容器.这限制了类型安全地使用HashMap,如单一的值类型.但如果想混合苹果和梨,该怎样做呢? 幸运的是,有一个简单的设计模式允许使用Java泛型映射不同的值类型,Joshua Bloch在其<Effective Java>(第二版,第29项)中将其描述为类型安全的异构容器(typesafe hetereogeneous Containe

  • Java Mybatis框架Dao层的实现与映射文件以及核心配置文件详解分析

    目录 Mybatis的Dao层实现 传统开发方式 代理开发方式 MyBatis映射文件深入 动态sql语句 动态SQL之<if> 动态SQL之<foreach> SQL片段抽取 总结 Mybatis核心配置文件深入 typeHandlers标签 plugins标签 总结 Mybatis的Dao层实现 传统开发方式 1.编写UserDao接口 public interface UserMapper { public List<User> findAll() throws

  • SpringBoot解析yml全流程详解

    目录 背景 加载监听器 执行run方法 加载配置文件 封装Node 调用构造器 思考 背景 前几天的时候,项目里有一个需求,需要一个开关控制代码中是否执行一段逻辑,于是理所当然的在yml文件中配置了一个属性作为开关,再配合nacos就可以随时改变这个值达到我们的目的,yml文件中是这样写的: switch: turnOn: on 程序中的代码也很简单,大致的逻辑就是下面这样,如果取到的开关字段是on的话,那么就执行if判断中的代码,否则就不执行: @Value("${switch.turnOn}

  • Android中gson、jsonobject解析JSON的方法详解

    JSON的定义: 一种轻量级的数据交换格式,具有良好的可读和便于快速编写的特性.业内主流技术为其提供了完整的解决方案(有点类似于正则表达式 ,获得了当今大部分语言的支持),从而可以在不同平台间进行数据交换.JSON采用兼容性很高的文本格式,同时也具备类似于C语言体系的行为. JSON对象: JSON中对象(Object)以"{"开始, 以"}"结束. 对象中的每一个item都是一个key-value对, 表现为"key:value"的形式, ke

  • Hibernate识别数据库特有字段实例详解

    Hibernate识别数据库特有字段实例详解 前言: Hibernate已经为绝大多数常用的数据库数据类型提供了内置支持,但对于某些数据库的专属字段支持就不够好了. 这些特殊数据类型往往提供了比常规数据类型更好的数据表达能力,更符合我们的业务场景.比如PostgreSQL的Interval类型,可以非常方便的保存一个时间段的数据. 本文以添加Interval类型支持为例,说明为Hibernate添加特有数据类型支持的方法. Hibernate提供了丰富的数据类型支持,但对于部分数据库专有的数据类

  • Java Hibernate使用SessionFactory创建Session案例详解

        SessionFactory在Hibernate中实际上起到了一个缓冲区的作用 他缓冲了HIbernate自动生成SQL语句和其他的映射数据 还缓冲了一些将来有可能重复利用的数据     为了能创建一个SessionFactory对象 应该在Hibernate初始化的时候创建一个Configuration类的实例 并将已经写好的映射文件交给他处理 这样Configuration对象就可以创建一个SessionFactory对象 当SessionFactory对象创建成功后 Configu

  • MyBatis XPathParser解析器使用范例详解

    MyBatis是优秀的开源数据库框架,本菜鸟抱着学习的态度,通过<MyBatis技术内幕>一书来进行MyBatis 的学习. MyBatis 的基础支撑层使用XPathParser来实现XML的解析,纸上得来终觉浅,本菜鸟决定亲自简单实践下XPathParser的使用,并在此做下备忘: 首先,XPathParser封装了XML的document对象,其构造方法较多,个人选了以下几个方法: 第一个是将XML内容作为一个字符串输入 public XPathParser(String xml) {

  • Python 网页解析HTMLParse的实例详解

    Python 网页解析HTMLParse的实例详解 使用python将网页抓取下来之后,下一步我们就应该解析网页,提取我们所需要的内容了,在python里提供了一个简单的解析模块HTMLParser类,使用起来也是比较简单的,解析语法没有用到XPath类似的简洁模式,但新手用起来还是比较容易的,看下面的例子: 现在一个模拟的html文件: <html> <title id='main' mouse='你好'>我是标题</title><body>我是内容<

随机推荐