本文依旧以Customer类和Order类进行说明。
一、引言
  Hibernate检索Customer对象时立即检索与之关联的Order对象,这种检索策略为立即检索策略。立即检索策略存在两大不足:
    A、select语句太多,而且会出现N+1的问题。所谓N+1,1是指先查出所有的Customer集合,N是指针对每个Customer再查询其关联的Order集合。N+1可以通过一条外连接查询语句完成。
    B、应用逻辑上可能并不需要Order集合,此时加载Order集合浪费内存空间。
  为解决上述问题,Hibernate提供了另外两种检索策略:延迟检索策略和迫切左外连接检索策略。
二、Hibernate的检索策略简介
  分两个层次:类级别检索策略和关联级别的检索策略。
  1、类级别和关联级别可选的检索策略及默认的检索策略

检索策略的作用域 可选的检索策略 默认的检索策略 运行时行为受影响的检索方法
类级别 立即检索
延迟检索
延迟检索 仅Session.load()方法。其余的都是立即检索
关联级别 立即检索
延迟检索
迫切左外连接检索
延迟检索 影响Session.load()及get()方法,Query API以及Criteria API。Query API会忽略映射文件中设定的迫切左外连接检索策略

  2、三种检索策略的允许机制

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

  3、用于设定检索策略的几个属性

属性 类级别 一对多关联级别 多对一关联级别
lazy <class>元素中可选值为:true(延迟)和false(立即) <set>元素中可选值:true(延迟)、extra(增强延迟)和false(立即) <many-to-one>元素中的可选值:proxy(延迟)、no-proxy(无代理延迟)和false(立即)
fetch <set>元素中可选值:select(select查询语句)、subselect(带子查询的查询语句)和join(迫切左外连接查询) <many-to-one>元素中可选值:select(select查询语句)、和join(迫切左外连接查询)
batch-size 设定批量检索的数量。仅适用于关联级别的立即检索和延迟检索。
备注 fetch属性取值为select或subselect时,决定初始化关联集合的查询语句的形式;取值为join时,决定集合被初始化的时机。若fetch属性为join,则lazy属性被忽略。

三、类级别的检索策略
  类级别可选的检索策略包含立即检索和延迟检索,默认是立即检索。
  通过以下配置文件:

<class name="mypack.Customer" table="CUSTOMERS" lazy="true/false">

  且只在Session.load()方法时生效,其返回的是一个代理对象,注意与其相关的几种异常。可以通过org.hibernate.Hibernate#initialize()方法显式初始化代理类实例。
四、一对多和多对多关联的检索策略
1、立即检索(lazy属性为false):慎用。
2、延迟检索(lazy属性为true):只有当应用程序第一次访问集合对象时才初始化,比如调用集合的iterator()\size()\isEmpty\contains()方法时。
3、增强延迟检索(lazy属性为extra):与延迟检索类似,但是只有调用集合的iterator()方法时,才会初始化集合对象。
4、批量延迟检索和批量立即检索(使用batch-size属性)
  该属性的设置可以对N+1的问题起到缓解效果。
  举例说明:一个Customer对象的orders集合中有10个对象,正常情况下全部加载会执行11条语句。
  设置了batch-size为4后,将会执行1+3条语句。

select * from CUSTOMERS;
select * from ORDERS where CUSTOMER_ID in (1,2,3,4);
select * from ORDERS where CUSTOMER_ID in (5,6,7,8);
select * from ORDERS where CUSTOMER_ID in (9,10);

5、用带子查询的select语句整批量初始化orders集合(fetch属性为subselect)
即在初始化集合时会采用子查询的方式。
当fetch属性为subselect时,batch-size属性失效。
6、迫切左外连接查询(fetch属性为join):直接使用左外连接查询初始化集合对象。
注意,当使用Query.list()时,该配置失效。
五、多对一和一对一关联的检索策略
1、迫切左外连接(fetch属性为join):与上述类似,注意和lazy属性的搭配。
2、延迟检索(lazy属性为proxy):对于一对一关联,如果使用延迟加载,必须把<one-to-one>元素的constrained属性设置为true。
3、无代理延迟加载(lazy属性为no-proxy):无代理的延迟检索会在order.getCustomer()时就进行初始化,而又代理的延迟加载时在访问Customer属性时初始化。
4、立即检索(lazy属性为false):与上述类似。
5、批量延迟检索和批量立即检索(使用batch-size属性):与上述类似。
六、控制迫切左外连接检索的深度
  通过hibernate.max_fetch_depth属性来控制,默认值为2.
七、属性级别的检索策略
  主要是针对<property><component>元素,适合于二进制大对象、字符串大对象及大容量组件类型的属性。

攻城狮在路上(壹) Hibernate(十二)--- Hibernate的检索策略的更多相关文章

  1. 攻城狮在路上(壹) Hibernate(十八)--- 管理Hibernate的缓存

    一般Session的缓存被称为Hibernate的第一级缓存,SessionFactory的外置缓存是一个可配置的缓存插件,称为Hibernate的第二级缓存.一.缓存的基本原理: 1.持久化层的缓存 ...

  2. 攻城狮在路上(壹) Hibernate(十六)--- Hibernate声明数据库事务

    一.数据库事务的概念: 数据库的ACID特征:Atomic.Consistency.Isolation.Durability.原子性.一致性.隔离性.持久性.不同的隔离级别引发的不同问题. 事务的AC ...

  3. 攻城狮在路上(壹) Hibernate(十四)--- Hibernate的检索方式(下)

    本节介绍HQL和QBC的高级用法:各种连接查询.投影查询.报表查询.动态查询.集合过滤和子查询等.另外将归纳优化查询程序代码,从而提高查询性能的各种技巧.一.连接查询: HQL与QBC支持的各种连接类 ...

  4. 攻城狮在路上(壹) Hibernate(十三)--- Hibernate的检索方式(上)

    Hibernate提供了以下几种检索对象的方式: A.导航对象图检索方式. B.OID检索方式.Session.get() load(); C.HQL检索方式.Query. D.QBC检索方式.Que ...

  5. 攻城狮在路上(壹) Hibernate(九)--- Hibernate的映射类型

    Hibernate采用映射类型作为Java类型和SQL类型的桥梁,对应type属性.分为两种:内置映射类型和客户化映射类型.一.内置映射类型: 1.Java基本类型的Hibernate映射类型: Ja ...

  6. 攻城狮在路上(壹) Hibernate(七)--- 通过Hibernate操纵对象(下)

    一.与触发器协同工作: 当Hibernate与数据库的触发器协同工作时,会出现以下两类问题: 1.触发器使Session缓存中的数据和数据库中的不一致: 出现此问题的原因是触发器运行在数据库内,它执行 ...

  7. 攻城狮在路上(壹) Hibernate(六)--- 通过Hibernate操纵对象(上)

    一.Hibernate缓存简介: Session接口是Hibernate向应用程序提供的操纵数据接口的最主要接口,它提供了基本的保存.更新.删除和加载Java对象的方法. Session具有一个缓存, ...

  8. 攻城狮在路上(壹) Hibernate(三)--- 属性访问、命名策略、派生属性、指定包名等

    一.hibernate访问持久化类属性的策略: 在<property>元素中的access属性用于指定Hibernate访问持久化类属性的方式. 常见的方式如下: 1.property:默 ...

  9. 攻城狮在路上(壹) Hibernate(二)--- 第一个hibernate程序

    1.直接通过JDBC API持久化实体域对象: A.java.sql常用接口和类: DriverManager:驱动程序管理器,负责创建数据库连接. Connection:代表数据库连接. State ...

随机推荐

  1. Validform —— 再也不用担心“表单验证”!

    <!doctype html> <html> <head> <meta content="text/html" charset=" ...

  2. SVN权限管理

    转自:http://www.cnblogs.com/xingchen/archive/2010/07/22/1782684.html /******************************** ...

  3. 2.6---找有环链表的开头结点(CC150)

    public ListNode detectCycle(ListNode head) { ListNode fast = head; ListNode slow = head; int flag = ...

  4. django xadmin 外键

    style_fields = {'db栏位名称': "fk-ajax"} 实体关系: Account (*)-->(1) user 表单控件: 下拉框 美化用了selecti ...

  5. Postman

    Postman功能(https://www.getpostman.com/features) 主要用于模拟网络请求包 快速创建请求 回放.管理请求 快速设置网络代理 安装 下载地址:https://w ...

  6. IIS 处理请求 原理

    有时候我们会发现当我们访问一个IIS网站时,使用网址可以正常访问,但是使用IP却不行,这是什么原因呢? 原来IIS可以使用一个IP地址和端口绑定多个网站,这些网站的IP地址与端口都一样,因此在客户端或 ...

  7. freemodbus-v1.5.0 源码分析

    注:转载请注明出处   http://www.cnblogs.com/wujing-hubei/p/5935142.html FreeModbus协议栈作为从机,等待主机传送的数据,当从机接收到一帧完 ...

  8. centos7删除已经安装的docker

    centos下可以使用yum来删除docker. 列出docker包的具体的名字. $ yum list installed | grep docker docker-engine.x86_64 -0 ...

  9. Linux下安装gcc和g++

    以CentOS为例,安装后是没有C语言和C++编译环境的,需要手动安装,最简单的是用yum的方式安装,过程如下: 1.安装gcc yum install gcc 询问是否,按y键回车即可,或者 yum ...

  10. Androd核心基础01

    Androd核心基础01包含的主要内容如下 Android版本简介 Android体系结构 JVM和DVM的区别 常见adb命令操作 Android工程目录结构 点击事件的四种形式 电话拨号器Demo ...