攻城狮在路上(壹) 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 ...
随机推荐
- IDEA 编译找不到符号,文件却没有错误。
单独编译提交找不到符号的文件. DIEAA
- jquery学习——选择器
一.基础选择 1.$("*") 选择所有元素 2.$(".class") 选择某个类 3.$("#id") 选择某个id 4.$(" ...
- DOM高级
表格应用 获取 tBodies, tHead, tFoot, rows, cells 隔行变色 鼠标移入高亮, 添加,删除一行 DOM的方法使用 <!DOCTYPE html PUBLIC &q ...
- java 调用webservice的各种方法总结
java 调用webservice的各种方法总结 几种流行的开源WebService框架Axis1,Axis2,Xfire,CXF,JWS比较 方法一:创建基于JAX-WS的webservice(包括 ...
- python: extend (扩展) 与 append (追加) 的差别
>>> li = ['a', 'b', 'c'] >>> li.extend(['d', 'e', 'f']) >>> li ['a', 'b', ...
- iOS coredata 级联删除
应用场景如下,每个用户可以设定多个提醒,当删除一个用户时,应当把相关的提醒都删除,而删除一个提醒时,应当把提醒从用户信息中删除. 那么 Profile 应该建立一个如下图的relationship 而 ...
- 基于Maven构建开发第一个Storm项目
前面说过了Storm的测试项目,那么此时我们更想自己写一个小项目来练练手,首先我们自己的Windows系统上首先应该安装好maven,然后启动Eclipse for JavaEE版本,接下来开始建立项 ...
- 【网络】VPN
VPN: 来自百度百科 虚拟专用网络的功能是:在公用网络上建立专用网络,进行加密通讯.在企业网络中有广泛应用.VPN网关通过对数据包的加密和数据包目标地址的转换实现远程访问.VPN有多种分类方式,主要 ...
- iOS block 的底层实现
其实swift 的闭包跟 OC的block 是一样一样的,学会了block,你swift里边的闭包就会无师自通. 参考:http://www.jianshu.com/p/e23078c11518 ht ...
- 在springMVC的controller层获取view层的参数的方式
方法一:request.getParameter("name") 方法二:注解@RequestParam @RequestMapping("testRequestPara ...