Hibernate5笔记6--Hibernate检索优化
Hibernate检索优化:
检索即查询。为了减轻DB的访问压力,提高检索效率,Hibernate对检索进行了优化。
所谓检索优化,指的是对查询语句的执行时机进行了细致、严格的把控:并不是代码中一出现查询语句,马上就在后台调用执行select语句。而是在代码中真正需要时才执行select。即将select的执行进行了最大可能的“延迟”。
对对象进行检索的目的是为了将对象加载到内存,让程序使用其数据。所以,对象检索也称为对象加载。根据检索对象的不同,可以将检索优化分为两类: (1)当前对象检索优化 (2)关联对象检索优化
对于不使用优化进行对象检索的过程,称为直接加载;否则称为延迟加载,或懒加载。 延迟加载的底层实现,在Hibernate3.3版本之前使用的是CGLIB生成代理实现的,而3.3版本以后是由javassist代理实现的。若实体类使用final修饰,将无法生成CGLIB代理,即对于3.3版本之前的Hibernate将无法实现延迟加载。考虑到对老版本代码的兼容问题,实体类最好不要使用final修饰。
(1)当前对象检索优化:
对于当前对象进行检索加载,Session中提供了两个方法:get()与load()。 默认情况下,get()为直接加载,而load()为延迟加载。
get()方法的直接加载指,当代码中出现get()时,后台马上会调用执行select语句,将对象直接加载到内存。
load()方法的延迟加载指,当代码中出现load()时,后台并不会马上调用执行select。只有当代码中真正在访问除了主键id属性以外的其它属性时,才会真正执行select语句,即此时才会将对象真正加载到内存。
load()方法默认情况下采用延迟加载策略,但也是可以改变的,可以改为直接加载。在该类映射文件的<class/>标签中有个属性lazy,其默认值为true,即采用延迟加载策略。将其值修改为false,load()的执行也将采用直接加载。
(2)关联对象检索优化:
对于关联对象的检索,也可进行延迟加载的优化。采用何种优化策略,要依据映射文件的配置。映射文件中对于关联对象检索的优化配置属性有两个:lazy、fetch。
lazy与fetch各具有若干值,它们不同值的组合,表示不同的对象加载策略。 根据这两个属性配置位置的不同,又分为两种: (1)多端配置优化 (2)单端配置优化
(1)多端加载优化(在一方对象的映射文件中配置属性):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.tongji.beans">
<class name="Country">
<id name="cid">
<generator class="native"/>
</id>
<property name="cname"/>
<!-- 左外连接查询,不存在延迟加载问题,也就不存在多端加载优化问题 ,所以不用lazy-->
<!-- <set name="ministers" cascade="all" fetch="join"> -->
<!-- 普通查询(两表分别查询),不使用延迟加载,则查找当前对象的时候,不管关联对象是否用到,都会一起加载 -->
<!-- <set name="ministers" cascade="all" fetch="select" lazy="false"> -->
<!-- 普通查询,使用延迟加载,则查找当前对象的时候,不加载关联对象,直到用到关联对象的时候,才会加载关联对象 -->
<!-- <set name="ministers" cascade="all" fetch="select" lazy="true"> -->
<!-- 普通查询,特别延迟,则查找当前对象的时候,不加载关联对象,并且用到关联对象的时候,能用聚合查询的时候,就不做详情查询 -->
<!-- <set name="ministers" cascade="all" fetch="select" lazy="extra"> -->
<!-- 补充:子查询,效果同普通查询,其实Hibernate5不支持该策略,但为了兼容以前的版本,对subselect进行了保留 -->
<!-- <set name="ministers" cascade="all" fetch="subselect" lazy="extra"> -->
<!-- 默认使用,fetch="select" lazy="true"这种格式 -->
<set name="ministers" cascade="save-update">
<key column="countryId"/>
<one-to-many class="Minister"/>
</set>
</class>
</hibernate-mapping>
测试代码:
@Test
public void test01() {
//1. 获取Session
Session session = HbnUtils.getSession();
try {
//2. 开启事务
session.beginTransaction();
//3. 操作
Country country = session.get(Country.class, 1);
Set<Minister> ministers = country.getMinisters();
//集合大小的输出
System.out.println("ministers.size() = " + ministers.size());
//集合详情的输出
System.out.println(ministers);
//4. 事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
//5. 事务回滚
session.getTransaction().rollback();
}
}
(2)单端加载优化(在多方对象的映射文件配置属性):
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.tongji.beans">
<class name="Minister">
<id name="mid">
<generator class="native"/>
</id>
<property name="mname"/>
<!-- 关联属性名 -->
<!-- 左外连接查询,同多端加载优化 -->
<!-- <many-to-one name="country" cascade="save-update"
class="Country" column="countryId" fetch="join"/> -->
<!-- 普通查询之直接加载,同多端加载优化 -->
<!-- <many-to-one name="country" cascade="save-update"
class="Country" column="countryId" fetch="select" lazy="false"/> -->
<!-- 普通查询,是否延迟加载,由关联对象的lazy值决定-->
<many-to-one name="country" cascade="save-update"
class="Country" column="countryId" fetch="select" lazy="proxy"/>
<!-- 补充:no-proxy和proxy基本相同,但是会对字节码进行加强 -->
<!-- <many-to-one name="country" cascade="save-update"
class="Country" column="countryId" fetch="select" lazy="no-proxy"/> -->
</class>
</hibernate-mapping>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping package="com.tongji.beans">
<!-- 单端加载优化,之普通查询,直接加载-->
<!-- <class name="Country" lazy="false"> -->
<!-- 单端加载优化,之普通查询,延迟加载 ,默认-->
<class name="Country" lazy="true">
<id name="cid">
<generator class="native"/>
</id>
<property name="cname"/>
<set name="ministers" cascade="all">
<key column="countryId"/>
<one-to-many class="Minister"/>
</set>
</class>
</hibernate-mapping>
测试代码:
@Test
public void test01() {
//1. 获取Session
Session session = HbnUtils.getSession();
try {
//2. 开启事务
session.beginTransaction();
//3. 操作
Minister minister = session.get(Minister.class, 2);
Country country = minister.getCountry(); System.out.println("country.id = " + country.getCid());
System.out.println("country.name = " + country.getCname());
//4. 事务提交
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
//5. 事务回滚
session.getTransaction().rollback();
}
}
Hibernate5笔记6--Hibernate检索优化的更多相关文章
- Hibernate检索策略(抓取策略)(Hibernate检索优化)
一.查询方法中get方法采用策略是立即检索,而load方法采用策略是延迟检索,延迟检索是在使用数据时才发送SQL语句加载数据 获取延迟加载数据方式:1.使用的时候,如果Customer c=sessi ...
- Hibernate学习---检索优化
Hibernate框架对检索进行了优化,前面我们将CURD的时候提到了load和get的区别,当时仅仅说了load为延迟加载,get为立即加载,当检索的记录为空的时候load报错(不是在执行load方 ...
- Hibernate —— 检索策略
一.Hibernate 的检索策略本质上是为了优化 Hibernate 性能. 二.Hibernate 检索策略包括类级别的检索策略.和关联级别的检索策略(<set> 元素) 三.类级别的 ...
- 7.Hibernate 检索
1.Hibernate检索方式 检索方式简介: 导航对象图检索方式:根据已经加载的对象,导航到其他对象.OID检索方式:按照对象的OID来检索对象.Session 的 get() 和 load() 方 ...
- Hibernate的优化方案
使用参数绑定 使用绑定参数的原因是让数据库一次解析SQL,对后续的重复请求可以使用生成好的执行计划,这样做节省CPU时间和内存. 避免SQL注入. 尽量少使用NOT 如果where子句中包含not关键 ...
- (转)Hibernate的优化方案
http://blog.csdn.net/yerenyuan_pku/article/details/70768603 HQL优化 使用参数绑定 使用绑定参数的原因是让数据库一次解析SQL,对后续的 ...
- Hibernate入门6.Hibernate检索方式
Hibernate入门6.Hibernate检索方式 20131128 代码下载 链接: http://pan.baidu.com/s/1Ccuup 密码: vqlv Hibernate的整体框架已经 ...
- spring +hibernate 启动优化【转】
最近在负责一个大项目,项目组成员包括项目经理大概10个人左右.项目技术用struts+spring+hibernate实现.项目的规模相对来说是比较大的,总共有10大模块,每个大模块又分为有十几个.甚 ...
- Hibernate性能优化之EHCache缓存
像Hibernate这种ORM框架,相较于JDBC操作,需要有更复杂的机制来实现映射.对象状态管理等,因此在性能和效率上有一定的损耗. 在保证避免映射产生低效的SQL操作外,缓存是提升Hibernat ...
随机推荐
- P4645 [COCI2006-2007 Contest#3] BICIKLI
题意翻译 给定一个有向图,n个点,m条边.请问,1号点到2号点有多少条路径?如果有无限多条,输出inf,如果有限,输出答案模10^9的余数. 两点之间可能有重边,需要看成是不同的路径. 题目描述 A ...
- UOJ #126 【NOI2013】 快餐店
题目链接:快餐店 震惊!某ZZ选手此题调了一天竟是因为……>>点击查看 一般碰到这种基环树的题都要先想想树上怎么做.这道题如果是在树上的话……好像求一遍直径就做完了?答案就是直径长度的一半 ...
- linux内核设计与实现一书阅读整理 之第十八章
CHAPTER 18 调试 18.1 准备开始 需要的是准备是: - 一个bug - 一个藏匿bug的内核版本 - 相关内核代码的知识和运气 重点: 想要成功的进行调试,就取决于是否能让这些错误重现. ...
- bzoj 1212: [HNOI2004]L语言 AC自动机+状压
为什么这道题网上所有题解写的都是N*Len的trie树的暴力啊,4E的复杂度... 为什么暴力还跑这么快啊TAT.. 有一个O(Len)的做法就是先把AC自动机建出来,因为每个字典串的长度很小,所以我 ...
- FPGA/SOPC学习转载
转自小時不識月http://www.cnblogs.com/yuphone/archive/2010/08/27/docs_plan.html 新网址为:http://andrewz.cn [连载计划 ...
- [poj 1533]最长上升子序列nlogn树状数组
题目链接:http://poj.org/problem?id=2533 其实这个题的数据范围n^2都可以过,只是为了练习一下nlogn的写法. 最长上升子序列的nlogn写法有两种,一种是变形的dp, ...
- 【Asp.net入门04】第一个ASP.NET 应用程序-如何添加Web窗体到网站中
添加Web窗体 本部分内容: 什么是web form 怎样添加web form 1.添加Web窗体到项目中 Web 窗体是一项 ASP.NET 功能,您可以使用它为 Web 应用程序创建用户界面.We ...
- linux 命令操作记录
1.查找名为 migrations 的文件夹/文件,并删除 find . -name "migrations" -type d #查找当前目录下文件夹名为 migrations 的 ...
- samba和nginx服务
samba和nginx服务 1.s配置amba samba的功能: samba是一个网络服务器,用于Linux和Windows之间共享文件. 1.1配置环境 关闭防火墙和selinux systemc ...
- unity解析json的两种方式
一直比较钟情于json,用来做数据交互,堪称完美!下面简单说一下unity使用C#脚本如何解析json数据吧. 一.写解析类,借助于JsonUtility.FromJson 直接给个例子吧 1.jso ...