8、Hibernate 高级教程 - 概述

2019-07-03

本文是在进行Hibernate检索策略学习过程中所总结的知识点的第二部分。其中在第一部分中,已经学习了类级别的检索策略以及1-N和N-N的检索策略。在该文中将学习N-1和1-1的检索策略,并对检索策略进行总结。

Hibernate:检索策略的学习1 Hibernate:检索策略的学习2

N-1和1-1的检索策略


这个小节中的内容其实与第二部分的关于1-N和N-N部分有很多相似之处。只不过操作的对象不一样。比如说,我们之前考虑的是在获得了Customer时,如何获取其对应的orders集合;而在该节,我们考虑的是,在获取了Order对象,如何获取相对应的Customer。

在这里,我们需要考虑的是在Order.hbm.xml中的 标签的属性,同样,其也有lazy属性和fetch属性:

lazy属性(默认值proxy) fetch属性(默认值select) 检索Order对象时对关联的Customer对象使用的检索策略
proxy 未设置(取默认值select) 采用延迟检索策略
no-proxy 未设置(取默认值select) 无代理延迟检索策略
false 未设置(取默认值select) 立即检索
proxy join 迫切左外连接检索

需要注意的点:

  • 若fetch属性设置为join,那么lazy属性将被忽略;
  • 迫切左外连接检索策略的优点在于比立即检索策略使用的SELECT语句更少;
  • no-proxy延迟检索需要增强持久化类的字节码才能实现。
  • Query的list方法会忽略映射文件配置的迫切左外连接检索策略(join),而采用延迟检索策略。

如果在关联级别使用了延迟加载或立即加载检索策略,可以设定批量检索的大小,以帮助提高延迟检索或立即检索的运行性能。该属性需要设置在 1 那一的 class 元素中,也就是Customer的 元素: <class name="Customer" table="CUSTOMERS" lazy="true" batch-size="5">。其作用可以批量的初始化Customer对象。

总结


类级别和关联级别可选的检索策略

检索策略作用域 可选检索策略 默认检索策略 运行时行为受影响的检索方法
类级别 立即检索
延迟检索
延迟检索 仅影响Session的load()方法
关联级别 立即检索
延迟检索
迫切左外连接检索
延迟检索 影响Session的load()方法和get()方法,以及Query API和Criteria
API,例外情况是Query API会忽略迫切左外连接策略

3种检索策略的运行机制

检索策略类型 类级别 关联级别
立即检索 立即加载检索方法指定的对象 立即加载与检索方法指定的对象的关联对象,可以设定批量检索数量
延迟检索 延迟加载检索方法指定的对象 延迟加载与检索方式指定的对象的关联对象,可以设定批量检索数量
迫切左外连接 不适用 通过左外连接加载与检索方法指定的对象的关联对象

设定检索策略的属性

lazy

  • 类级别
    • 元素中lazy属性的可选值为true(延迟检索)和false(立即检索)
    • 元素的lazy属性默认为true
  • 1-N和N-N关联级别
    • 元素中lazy属性的可选值为true(延迟检索)和false(立即检索)
    • 元素的lazy属性默认为true
  • 多对多关联级别
    • 元素中lazy属性的可选值为proxy(延迟检索)、no-proxy(无代理延迟检索)和false(立即检索)
    • 元素的lazy属性默认为proxy

fetch

  • 类级别
    • 没有此属性
  • 1-N和N-N关联级别
    • 元素中fetch属性的可选值为select(select查询语句)、subselect(带子查询的select语句)和join(迫切左外连接检索)
    • 元素的fetch属性默认为select
  • N-1和1-1关联级别
    • 元素中fetch属性的可选值为select(select查询语句)和join(迫切左外连接检索)
    • 元素的fetch属性默认为select

batch-size

设定批量检索的数量,可选值为一个正整数,默认值为1。如果设定此项,合理的取值在3-10之间。仅适用于关联级别的立即检索和延迟检索,在 元素中包含此属性

三种检索策略比较

立即检索

  1. 优点:对应用程序完全透明,无论对象处于持久化状态还是游离状态(session是否关闭),应用程序可以方便的从一个对象导航到与它相关的对象。
  2. 缺点:select语句数目多,可能会加载应用程序不需要访问的对象,白白浪费内存空间。
  3. 优先考虑的场合:(1)类级别;(2)应用程序需要立即访问的对象;(3)使用了二级缓存

延迟检索

  1. 优点:由应用程序决定需要加载哪些对象,可以避免执行多余的select语句,以及避免加载应用程序不需要访问的对象。因此能提高检索性能,并且节省内存空间。
  2. 缺点:应用程序如果希望访问游离状态的代理类实例,必须保证它在持久化状态已经被初始化。
  3. 优先考虑的场合:(1)1-N关联或者N-N关联;(2)应用程序不需要立即访问或者根本不会访问的对象

迫切左外连接检索

  1. 优点:对应用程序完全透明,不管对象处于持久状态,还是游离状态,应用程序可以方便的从一个对象导航到与它相关的对象。
  2. 缺点:可能会加载应用程序不需要访问的对象,白白浪费内存空间;复杂的数据库表连接也会影响检索性能。
  3. 优先考虑的场合:(1)N-1或者N-N关联;(2)应用程序需要立即访问的对象;(3)数据库具有良好的表连接性能。