Hibernate 检索策略
2016-04-11 20:54
405 查看
检索策略
1 概述
在查询数据库时,通常可以从两个方面提升程序的性能:
①节约内存空间
当应用程序需要读取Customer对象的数据并从数据库中将Customer对象加载到内存中,如果同时加载所有关联的Order对象的集合,但是又不使用,那么这些关联的Order对象就白白浪费了许多内存空间。
②少发送SQL语句
每发送一次SQL语句就需要获取一个数据库连接,与数据库进行一次完整的交互过程,而访问数据库往往是一个非常耗时的操作,应尽量减少访问数据库的次数。
2 类级别的检索策略:
load()方法的行为
①默认情况下加载对象时使用延迟检索策略,仅返回代理对象
②使用立即检索时,在方法执行时就加载全部数据
3 访问n的一端时的检索策略
①默认情况
加载Customer的时候,不会自动立即加载关联的Order集合
②延迟加载
在Customer的set元素内设置lazy=”false”后就会在加载Customer的同时发送加载Order集合的SQL语句。注意:这里虽然使用了立即加载策略但是并没有合并成一条SQL语句,而是使用了两条SQL语句
延迟检索的SQL
在访问Order集合的数据之前
在访问Order集合的数据之后
立即检索的SQL
在访问Order集合的数据之前
ORDER02
ORDER01
在访问Order集合的数据之后
③增强的延迟加载
使用lazy属性的extra值表示进一步推迟将数据加载到内存的时机,例如:查询关联的集合的长度时,只发送一条count函数SQL语句
④batch-size
使用set元素的batch-size属性可以设置在内存中一次性初始化关联的Order集合的个数,减少发送SQL语句的次数。例如:内存中有5个Customer,batch-size=2
【注意:当lazy=时,batch-size设置无效】
order集合长度:2
order集合长度:3
⑤set元素的fetch属性
[1]select:默认值
[2]subselect:忽略batch-size的设置,以子查询的方式加载全部的Order集合。
order集合长度:2
order集合长度:3
order集合长度:1
order集合长度:1
order集合长度:0
[3]join时:会在加载Customer对象的时候,就“迫不及待”的查询关联的Order集合,这样的检索方式我们在Hibernate中称之为“迫切左外连接”。
注意:取值为join时,会忽略lazy属性的设置。但是fetch=join对HQL查询无效。
4 访问1的一端
①立即检索
在many-to-one元素中设置lazy=”false”
Tip:在many-to-one元素中lazy属性的可选值是:false、proxy、no-proxy,其中默认值是proxy。
②迫切左外连接
将fetch属性设置为join即可
③batch-size
当查询了一组Order,内存中存在多个Customer时,可以在Customer.hbm.xml文件的class元素中设置batch-size属性,决定加载一组Order集合时同时初始化Customer对象的个数。例如:内存中有4个Customer需要初始化,batch-size设置为3时:
1 概述
在查询数据库时,通常可以从两个方面提升程序的性能:
①节约内存空间
当应用程序需要读取Customer对象的数据并从数据库中将Customer对象加载到内存中,如果同时加载所有关联的Order对象的集合,但是又不使用,那么这些关联的Order对象就白白浪费了许多内存空间。
②少发送SQL语句
每发送一次SQL语句就需要获取一个数据库连接,与数据库进行一次完整的交互过程,而访问数据库往往是一个非常耗时的操作,应尽量减少访问数据库的次数。
2 类级别的检索策略:
load()方法的行为
①默认情况下加载对象时使用延迟检索策略,仅返回代理对象
②使用立即检索时,在方法执行时就加载全部数据
< class name ="Customer" table ="CUSTOMERS" lazy ="false">
3 访问n的一端时的检索策略
①默认情况
加载Customer的时候,不会自动立即加载关联的Order集合
②延迟加载
在Customer的set元素内设置lazy=”false”后就会在加载Customer的同时发送加载Order集合的SQL语句。注意:这里虽然使用了立即加载策略但是并没有合并成一条SQL语句,而是使用了两条SQL语句
延迟检索的SQL
Hibernate: select customer0_.CUST_ID as CUST_ID1_0_0_, customer0_.CUST_NAME as CUST_NAM2_0_0_ from CUSTOMERS customer0_ where customer0_.CUST_ID=?
在访问Order集合的数据之前
Hibernate: select orderset0_.CUST_ID_FK as CUST_ID_3_0_1_, orderset0_.ORDER_ID as ORDER_ID1_1_1_, orderset0_.ORDER_ID as ORDER_ID1_1_0_, orderset0_.ORDER_NAME as ORDER_NA2_1_0_, orderset0_.CUST_ID_FK as CUST_ID_3_1_0_ from ORDERS orderset0_ where orderset0_.CUST_ID_FK=? ORDER01 ORDER02
在访问Order集合的数据之后
立即检索的SQL
Hibernate: select customer0_.CUST_ID as CUST_ID1_0_0_, customer0_.CUST_NAME as CUST_NAM2_0_0_ from CUSTOMERS customer0_ where customer0_.CUST_ID=?
Hibernate:
select
orderset0_.CUST_ID_FK as CUST_ID_3_0_1_,
orderset0_.ORDER_ID as ORDER_ID1_1_1_,
orderset0_.ORDER_ID as ORDER_ID1_1_0_,
orderset0_.ORDER_NAME as ORDER_NA2_1_0_,
orderset0_.CUST_ID_FK as CUST_ID_3_1_0_
from
ORDERS orderset0_
where
orderset0_.CUST_ID_FK=?
在访问Order集合的数据之前
ORDER02
ORDER01
在访问Order集合的数据之后
③增强的延迟加载
使用lazy属性的extra值表示进一步推迟将数据加载到内存的时机,例如:查询关联的集合的长度时,只发送一条count函数SQL语句
Hibernate: select customer0_.CUST_ID as CUST_ID1_0_0_, customer0_.CUST_NAME as CUST_NAM2_0_0_ from CUSTOMERS customer0_ where customer0_.CUST_ID=?
Hibernate:
select
count(ORDER_ID)
from
ORDERS
where
CUST_ID_FK =?
2
④batch-size
使用set元素的batch-size属性可以设置在内存中一次性初始化关联的Order集合的个数,减少发送SQL语句的次数。例如:内存中有5个Customer,batch-size=2
【注意:当lazy=时,batch-size设置无效】
Hibernate: select customer0_.CUST_ID as CUST_ID1_0_, customer0_.CUST_NAME as CUST_NAM2_0_ from CUSTOMERS customer0_ customer的个数:5 Hibernate: select orderset0_.CUST_ID_FK as CUST_ID_3_0_1_, orderset0_.ORDER_ID as ORDER_ID1_1_1_, orderset0_.ORDER_ID as ORDER_ID1_1_0_, orderset0_.ORDER_NAME as ORDER_NA2_1_0_, orderset0_.CUST_ID_FK as CUST_ID_3_1_0_ from ORDERS orderset0_ where orderset0_.CUST_ID_FK in ( ?, ? )
order集合长度:2
order集合长度:3
Hibernate: select orderset0_.CUST_ID_FK as CUST_ID_3_0_1_, orderset0_.ORDER_ID as ORDER_ID1_1_1_, orderset0_.ORDER_ID as ORDER_ID1_1_0_, orderset0_.ORDER_NAME as ORDER_NA2_1_0_, orderset0_.CUST_ID_FK as CUST_ID_3_1_0_ from ORDERS orderset0_ where orderset0_.CUST_ID_FK in ( ?, ? ) order集合长度:1 order集合长度:1 Hibernate: select orderset0_.CUST_ID_FK as CUST_ID_3_0_1_, orderset0_.ORDER_ID as ORDER_ID1_1_1_, orderset0_.ORDER_ID as ORDER_ID1_1_0_, orderset0_.ORDER_NAME as ORDER_NA2_1_0_, orderset0_.CUST_ID_FK as CUST_ID_3_1_0_ from ORDERS orderset0_ where orderset0_.CUST_ID_FK=? order集合长度:0
⑤set元素的fetch属性
[1]select:默认值
[2]subselect:忽略batch-size的设置,以子查询的方式加载全部的Order集合。
Hibernate: select customer0_.CUST_ID as CUST_ID1_0_, customer0_.CUST_NAME as CUST_NAM2_0_ from CUSTOMERS customer0_ customer的个数:5 Hibernate: select orderset0_.CUST_ID_FK as CUST_ID_3_0_1_, orderset0_.ORDER_ID as ORDER_ID1_1_1_, orderset0_.ORDER_ID as ORDER_ID1_1_0_, orderset0_.ORDER_NAME as ORDER_NA2_1_0_, orderset0_.CUST_ID_FK as CUST_ID_3_1_0_ from ORDERS orderset0_ where orderset0_.CUST_ID_FK in ( select customer0_.CUST_ID from CUSTOMERS customer0_ )
order集合长度:2
order集合长度:3
order集合长度:1
order集合长度:1
order集合长度:0
[3]join时:会在加载Customer对象的时候,就“迫不及待”的查询关联的Order集合,这样的检索方式我们在Hibernate中称之为“迫切左外连接”。
注意:取值为join时,会忽略lazy属性的设置。但是fetch=join对HQL查询无效。
4 访问1的一端
①立即检索
在many-to-one元素中设置lazy=”false”
Tip:在many-to-one元素中lazy属性的可选值是:false、proxy、no-proxy,其中默认值是proxy。
Hibernate:
select
order0_.ORDER_ID as ORDER_ID1_1_0_,
order0_.ORDER_NAME as ORDER_NA2_1_0_,
order0_.CUST_ID_FK as CUST_ID_3_1_0_
from
ORDERS order0_
where
order0_.ORDER_ID=?
Hibernate: select customer0_.CUST_ID as CUST_ID1_0_0_, customer0_.CUST_NAME as CUST_NAM2_0_0_ from CUSTOMERS customer0_ where customer0_.CUST_ID=?
ORDER01
CUST01
②迫切左外连接
将fetch属性设置为join即可
Hibernate: select order0_.ORDER_ID as ORDER_ID1_1_1_, order0_.ORDER_NAME as ORDER_NA2_1_1_, order0_.CUST_ID_FK as CUST_ID_3_1_1_, customer1_.CUST_ID as CUST_ID1_0_0_, customer1_.CUST_NAME as CUST_NAM2_0_0_ from ORDERS order0_ left outer join CUSTOMERS customer1_ on order0_.CUST_ID_FK=customer1_.CUST_ID where order0_.ORDER_ID=? ORDER01 CUST01
③batch-size
当查询了一组Order,内存中存在多个Customer时,可以在Customer.hbm.xml文件的class元素中设置batch-size属性,决定加载一组Order集合时同时初始化Customer对象的个数。例如:内存中有4个Customer需要初始化,batch-size设置为3时:
Hibernate:
select
order0_.ORDER_ID as ORDER_ID1_1_,
order0_.ORDER_NAME as ORDER_NA2_1_,
order0_.CUST_ID_FK as CUST_ID_3_1_
from
ORDERS order0_
Hibernate:
select
customer0_.CUST_ID as CUST_ID1_0_0_,
customer0_.CUST_NAME as CUST_NAM2_0_0_
from
CUSTOMERS customer0_
where
customer0_.CUST_ID in (
?, ?, ?
)
CUST01
CUST01
CUST02
CUST02
CUST02
CUST03
Hibernate: select customer0_.CUST_ID as CUST_ID1_0_0_, customer0_.CUST_NAME as CUST_NAM2_0_0_ from CUSTOMERS customer0_ where customer0_.CUST_ID=?
CUST04
相关文章推荐
- 数据结构 --- 线性表学习(php模拟)
- 【html】:html中实现下拉列表
- RabbitMQ入门(一) —— 基本概念
- 山东省第一届ACM省赛 F SDUT 2156 Fairy tale
- YTU 3007: 顺序串的基本运算
- activiti自定义流程之整合(二):使用angular js整合ueditor创建表单
- 【 OpenCV学习笔记 002】OpenCV 2.4.9组件结构解析
- 解决“Dynamic Web Module 3.0 requires Java 1.6 or newer.”错误
- activiti自定义流程之整合(二):使用angular js整合ueditor创建表单
- 在VS2013中配置OpenCL开发 环境
- 楼层扔鸡蛋问题
- Mybaits 批量操作
- 嵌入式Linux中常见的问题
- Aandroid TV 基于Leanback支持最新MD设计的TV开发框架
- OpenCV中贝叶斯分类器相关的API及其用法
- opencv 鼠标操作SetMouseCallback()函数传递用户定义参数的问题
- 计算机图形学学习记录(二)
- Aandroid TV 基于Leanback支持最新MD设计的TV开发框架
- 啊啊
- 小sugar呀——入门——记录