Hibernate懒加载

举报
chenyu 发表于 2021/07/27 02:11:27 2021/07/27
【摘要】 在Hibernate框架中,当我们要访问的数据量过大时,明显用缓存不太合适, 因为内存容量有限 ,为了减少并发量,减少系统资源的消耗,这时Hibernate用懒加载机制来弥补这种缺陷,但是这只是弥补而不是用了懒加载总体性能就提高了。 我们所说的懒加载也被称为延迟加载,它在查询的时候不会立刻访问数据库,而是返回代理对象,当真正去使用对象的时候才会访问数据库。 实现懒加...

在Hibernate框架中,当我们要访问的数据量过大时,明显用缓存不太合适, 因为内存容量有限 ,为了减少并发量,减少系统资源的消耗,这时Hibernate用懒加载机制来弥补这种缺陷,但是这只是弥补而不是用了懒加载总体性能就提高了。

我们所说的懒加载也被称为延迟加载,它在查询的时候不会立刻访问数据库,而是返回代理对象,当真正去使用对象的时候才会访问数据库。

实现懒加载的前提:

1 实体类不能是final的

2 能实现懒加载的对象都是被CGLIB(反射调用)改写的代理对象,所以不能是final修饰的
3 须要asm,cglib两个jar包
4 相应的lazy属性为true
5 相应的fetch属性为select
下面几种可以实现懒加载功能:

1、   通过Session.load()实现懒加载

load(Object, Serializable):根据id查询 。查询返回的是代理对象,不会立刻访问数据库,是懒加载的。当真正去使用对象的时候才会访问数据库。

用load()的时候会发现不会打印出查询语句,而使用get()的时候会打印出查询语句。

使用load()时如果在session关闭之后再查询此对象,会报异常:could not initialize proxy – no Session。处理办法:在session关闭之前初始化一下查询出来的对象:Hibernate.initialize(user);

使用load()可以提高效率,因为刚开始的时候并没有查询数据库。但很少使用。

2、one-to-one(元素)懒加载:

懒加载默认是关闭的,只有基于外键关联方式的“一对一”才用懒加载。必需同时满足下面三个条件时才能实现懒加载

(主表不能有constrained=true,所以主表没有懒加载)

lazy!=false 2)constrained=true 3)fetch=select

3、one-to-many (元素)懒加载:

当我们查询的是主对象时,将person和idcard外连接查询出person对象和idcard对象没有懒加载。当我们查询的是从对象时,对于idcard所关联的person对象是懒加载。

这种关联方实质性懒加载是非常有效的,Hibernate默认对它就是使用懒加载的,默认就是以下条件:

1)lazy!=false 2)fetch=select

4、 many-to-one(元素)实现了懒加载。

多对一的时候,查询主对象时默认是懒加载。即:查询主对象的时候不会把从对象查询出来。

多对一的时候,查询从对象时默认是懒加载。即:查询从对象的时候不会把主对象查询出来。

hibernate3.0中lazy有三个值,true,false,proxy,默认的是lazy=”proxy”.具体设置成什么要看你的需求,并不是说哪个设置就是最好的。在<many-to-one>与<one-to-one>标签上:当为true时,会有懒加载特性,当为false时会产生N+1问题,比如一个学生对应一个班级,用一条SQL查出10个学生,当访问学生的班级属性时Hibernate会再产生10条SQL分别查出每个学生对应的班级.

lazy= 什么时候捉取

fetch= 捉取方式:select=关联查询;join=连接表的方式查询(效率高)

fetch=join时,lazy的设置将没有意义.

.5、many-to-many (元素) :

这种关联方实质性懒加载是非常有效的,Hibernate默认对它就是使用懒加载的,默认就是以下条件:

1)lazy!=false 2)fetch=select

6、.能够懒加载的对象都是被改写过的代理对象,当相关联的session没有关闭时,访问这些懒加载对象(代理对象)的属性(getId和getClass除外)hibernate会初始化这些代理,或用Hibernate.initialize(proxy)来初始化代理对象;当相关联的session关闭后,再访问懒加载的对象将出现异常。

7、抓取策略

a)        select:作为默认值,它的策略是当需要使用到关联对象的数据时另外单独发送select语句,抓取当前对象的关联对象的数据。即懒加载。

b)        join:他的策略时使用一条select语句用内连接来获取对象的数据和关联对象的数据,此时关联对象的懒加载失效。

除了上面说的在映射文件中配置,lazy=false之外,我们还可以通过以下方式来解决懒加载问题。

1.明确初始化:

在session还没有关闭时,访问一次xxxx.getXxx(),强制访问数据库。或者Hibernate.initialize(xxx)

2.openSessionView   这个往往需要过滤器配合使用

3.在ssh中,可以实现在service层,标注方式来解决懒加载。

本文地址:http://www.blogfshare.com/hibernate-lazy.html


文章来源: chenyu.blog.csdn.net,作者:chen.yu,版权归原作者所有,如需转载,请联系作者。

原文链接:chenyu.blog.csdn.net/article/details/49309049

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。