攻城狮在路上(壹) Hibernate(十二)--- Hibernate的检索策略
本文依旧以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的检索策略的更多相关文章
- 攻城狮在路上(壹) Hibernate(十八)--- 管理Hibernate的缓存
一般Session的缓存被称为Hibernate的第一级缓存,SessionFactory的外置缓存是一个可配置的缓存插件,称为Hibernate的第二级缓存.一.缓存的基本原理: 1.持久化层的缓存 ...
- 攻城狮在路上(壹) Hibernate(十六)--- Hibernate声明数据库事务
一.数据库事务的概念: 数据库的ACID特征:Atomic.Consistency.Isolation.Durability.原子性.一致性.隔离性.持久性.不同的隔离级别引发的不同问题. 事务的AC ...
- 攻城狮在路上(壹) Hibernate(十四)--- Hibernate的检索方式(下)
本节介绍HQL和QBC的高级用法:各种连接查询.投影查询.报表查询.动态查询.集合过滤和子查询等.另外将归纳优化查询程序代码,从而提高查询性能的各种技巧.一.连接查询: HQL与QBC支持的各种连接类 ...
- 攻城狮在路上(壹) Hibernate(十三)--- Hibernate的检索方式(上)
Hibernate提供了以下几种检索对象的方式: A.导航对象图检索方式. B.OID检索方式.Session.get() load(); C.HQL检索方式.Query. D.QBC检索方式.Que ...
- 攻城狮在路上(壹) Hibernate(九)--- Hibernate的映射类型
Hibernate采用映射类型作为Java类型和SQL类型的桥梁,对应type属性.分为两种:内置映射类型和客户化映射类型.一.内置映射类型: 1.Java基本类型的Hibernate映射类型: Ja ...
- 攻城狮在路上(壹) Hibernate(七)--- 通过Hibernate操纵对象(下)
一.与触发器协同工作: 当Hibernate与数据库的触发器协同工作时,会出现以下两类问题: 1.触发器使Session缓存中的数据和数据库中的不一致: 出现此问题的原因是触发器运行在数据库内,它执行 ...
- 攻城狮在路上(壹) Hibernate(六)--- 通过Hibernate操纵对象(上)
一.Hibernate缓存简介: Session接口是Hibernate向应用程序提供的操纵数据接口的最主要接口,它提供了基本的保存.更新.删除和加载Java对象的方法. Session具有一个缓存, ...
- 攻城狮在路上(壹) Hibernate(三)--- 属性访问、命名策略、派生属性、指定包名等
一.hibernate访问持久化类属性的策略: 在<property>元素中的access属性用于指定Hibernate访问持久化类属性的方式. 常见的方式如下: 1.property:默 ...
- 攻城狮在路上(壹) Hibernate(二)--- 第一个hibernate程序
1.直接通过JDBC API持久化实体域对象: A.java.sql常用接口和类: DriverManager:驱动程序管理器,负责创建数据库连接. Connection:代表数据库连接. State ...
随机推荐
- Tomcat异常 Multiple Contexts have a path of "/qqshl".解决方法
Tomcat异常 Multiple Contexts have a path of "/qqshl".解决方法 找到tomcat映射文件Service.xml,将文件中的conte ...
- Graph Valid Tree
Given n nodes labeled from 0 to n - 1 and a list of undirected edges (each edge is a pair of nodes), ...
- 如何用 Robotframework 来编写优秀的测试用例
介绍 这篇文档将会是一篇在「高层面」的怎么用 Robotframework 来编写优秀测试用例的原则.至于如何使用 Robotframework 来与您的待测试系统相作用这样的细节讨论是不包含在这篇文 ...
- 请不要用SECONDS_BEHIND_MASTER来衡量MYSQL主备的延迟时间【转】
本文来自:http://www.woqutech.com/?p=1116 MySQL 本身通过 show slave status 提供了 Seconds_Behind_Master ,用于衡量主备之 ...
- Make My GitHub Pages
https://git-scm.com/ https://pages.github.com/ 1.建立repository. 2.settings 3.选模板 4.Publish http://use ...
- ABAP 内表的行列转换-发货通知单-打印到Excel里
需要传入数据到Excel里的模板如上图所示 ********************** * 设计主要逻辑与原理说明 ...
- OKhttp的封装(下)
OKhttpManager2.Class 请求工具类 package com.example.administrator.okhttp3; import android.os.Handler; im ...
- 51nod 1070 Bash游戏 V4 (斐波那契博弈)
题目:传送门. 有一堆个数为n(n>=2)的石子,游戏双方轮流取石子,规则如下: 1)先手不能在第一次把所有的石子取完,至少取1颗: 2)之后每次可以取的石子数至少为1,至多为对手刚取的石子数的 ...
- 假期(codevs 3622)
题目描述 Description 经过几个月辛勤的工作,FJ决定让奶牛放假.假期可以在1-N天内任意选择一段(需要连续),每一天都有一个享受指数W.但是奶牛的要求非常苛刻,假期不能短于P天,否则奶牛不 ...
- 把Git Repository建到U盘上去(转)
把Git Repository建到U盘上去 转 把Git Repository建到U盘上去 Git很火.原因有三: 它是大神Linus Torvalds的作品,天然地具备神二代的气质和品质: 促进了生 ...