知识大全 hibernate的优化-懒加载(lazy)
Posted 实体
篇首语:少年乘勇气,百战过乌孙。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 hibernate的优化-懒加载(lazy)相关的知识,希望对你有一定的参考价值。
为了进一步优化Hibernate的性能 可以使用
延迟加载技术 管理数据抓取策略 进行缓存管理 等方面考虑来提高Hibernate的性能
延迟加载(load)
延迟加载(load)是Hibernate为提高程序执行效率而提供的一种机制 即只有真正使用该对象的数据时才会创建
延迟加载的过程 通过代理(Proxy)机制来实现延迟加载 Hibernate从数据库获取某一个对象数据时 获取某一个对象的集合属性值时 或获取某一个对象所关联的另一个对象时 由于没有使用该对象的数据(除标识符外) Hibernate并不从数据库加载真正的数据 而只是为该对象创建一个代理对象来代表这个对象 这个对象上的所有属性都为默认值 只有在真正需要使用该对象的数据时才创建这个真正的对象 真正从数据库中加载它的数据
当调用Session上的load()方法加载一个实体时 当Session加载某个实体时 会对这个实体中的集合属性值采用延迟加载 当Session加载某个实体时 会对这个实体所单端关联的另一个实体对象采用延迟加载
关闭延迟加载 在加载单个实体时 可以使用get()方法
对于实体中的集合属性 可以在这个集合的(<set> <bag> <list>…)添加属性lazy= false 单端关联另一个实体对象时 可以在映射文件中配置<one to one> <many to one> 添加属性lazy= false 注意 one to one不能有constrained=true(产生的sql语句中显示外键) 否则懒加载不起作用
Hibernate中默认采用延迟加载的情况主要有以下几种
? 当调用Session上的load()方法加载一个实体时会采用延迟加载
? 当Session加载某个实体时 会对这个实体中的集合属性值采用延迟加载 (one to many)
? 当Session加载某个实体时 会对这个实体所单端关联(one to one many to one)的另一个实体对象采用延迟加载
? 第二种和第三种的区别是 第二种情况下取消延时加载的方法是在单方即有set属性的一方的映射文件的set标签后设置懒加载的属性lazy= false ;第三种情况则是在多方即有many to one的一方的映射文件中的many to one标签后设置lazy= false
能够懒加载的对象都是被改写过的代理对象 当相关联的session没有关闭时 访问这些懒加载对象(代理对象)的属性(getId和getClass除外)hibernate会初始化这些代理 或用Hibernate initialize(proxy)来初始化代理对象 当相关联的session关闭后 再访问懒加载的对象将出现异常
抓取策略(fetch)
通过配置 抓取策略 来直接影响session的get()和load()方法的查询效果
单端关联<many to one><one to_one>上的抓取策略
可以给单端关联的映射元素添加fetch属性 select:延迟加载 join:在同一条select语句使用内连接来获得对象的数据和它关联对象的数据 此时关联对象的延迟加载失效
集合属性上的抓取策略
select:延迟加载 join:在同一条select语句使用内连接来获得对方的关联集合 此时关联集合上的lazy会失效 subselect:另外发送一条查询语句或子查询抓取 这个策略对HQL的查询也起作用
延迟加载案例分析
情况一 单个实体调用load()方法取消懒加载
[java]
package hbsi test;
import hibernate Session;
import junit Test;
import hbsi domain User;
import hbsi utils HibernateUtil;
publicclass TestLazy
//测试get()方法 get()方法不管你有没有用到 总会执行sql语句
@Test
publicvoid testGet()
Session session = HibernateUtil getSession()
User user = (User) session get(User class )
// System out println(user getName())
HibernateUtil close()
//这里要注意的是 即使关闭了session 使user处于托管状态 仍然可以可以使用user对象 这是因为虽然处于托管状态 但是这个对象是存在属性值的对象 并没有把他删除 只是隔绝了它与数据库的打交道的通道
System out println(user getName())
//测试load()方法 不执行sql语句 用到的时候才执行
@Test
publicvoid testLoad()
Session session = HibernateUtil getSession()
User user = (User) session load(User class )
//这里输出id也不会执行sql语句 直接从上面你传进去的id中获取id 没有从数据库中查找 所以也不执行sql语句
System out println(user getId())
//而输出name就不一样了 这时其实就是实例化了代理对象 这是的代理对象有了name的属性 这时即使你关闭了session 也可以通过这个对象获取到name;如果注释这句 即不实例化代理对象 又在关闭session后执行输出name属性 这时会报错 could not initialize proxy
// System out println(user getName())
HibernateUtil close()
System out println(user getName())
情况二 set集合上取消懒加载
//测试如果在映射文件中将集合属性中的懒加载设置为false后将连带着orders表中数据一块提出来 即两条select语句
[java]
@Test
publicvoid find()
Session session = HibernateUtil getSession()
Customer cus = (Customer) session get(Customer class )
System out println(cus getCname())
//用到下面这种方法输出会出现两天sql语句 而且是分开的 如果用到懒加载会出现先输出两条sql语句 在输出结果
//这里不能直接方法链式输出cus getOrd() getOname() 因为cus getOrd()返回的是一个set集合
Set<Orders> orders = cus getOrd()
System err println(orders size())
HibernateUtil close()
方法三 <one to one> <many to one> 取消懒加载
[java]
@Test
publicvoid find()
//默认使用懒加载 即用着一条sql语句就输出一条 如果设置延时加载为false后输出两条sql语句 将不需要的顾客信息也查出来
Session session = HibernateUtil getSession()
Orders ord = (Orders) session get(Orders class )
System out println(ord getOname())
cha138/Article/program/Java/ky/201311/28447相关参考
类名HibernateUtil packageantbeejeemodelutil; importjavalangreflectInvocationTargetException; impo
Hibernate的延迟加载,一个锋利的两面刀 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 延
Hibernae的延迟加载是一个非常常用的技术实体的集合属性默认会被延迟加载实体所关联的实体默认也会被延迟加载Hibernate通过这种延迟加载来降低系统的内存开销从而保证Hibernate的运行
做web开发的朋友都应该掌握前端优化这个技巧其中一个就是滚动延时加载这个技巧应用在了很多地方比如新浪微博网页版以下就为大家详细介绍需要的朋友可以参考下 为什么要延时加载呢?页面加载的时候
优化Javaapplets加载过程 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 大家知道在ja
优化JavaApplet的加载过程 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 大家知道在ja
Hibernate优化 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧! 数据库设计 A降低关联的
Hibernate是对JDBC的轻量级封装因此在很多情况下Hibernate的性能比直接使用JDBC存取数据库要低然而通过正确的方法和策略在使用Hibernate的时候还是可以非常接近直接使用JD
如何优化Hibernate? 以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!cha138/
一批量修改和删除 在Hibernate中如果需要对任何数据进行修改和删除操作都需要先执行查询操作在得到要修改或者删除的数据后再对该数据进行相应的操作处理在数据量少的情况下采用这种处理方式没有问题