【java】itoo项目实战之hibernate 懒加载优化性能

在做itoo 3.0
的时候,考评系统想要上线,就开始导入数据了,只导入学生2万条数据,但是导入的速度特别的慢,这个慢的原因是因为导入的时候进行了过多的IO操作。但是导入成功之后,查询学生的速度更加慢,因为底层用了hibernate的hql语句进行查询的,学习过hibernate的人都知道,如果hibernate不设置懒加载的话,只有是有关联的数据都会一次性全部都查询出来,我试了试,查询2万条数据,最深的级联查询是有5层,然后发出来的语句是460条,时间大概是10s。然后就考虑使用lazy进行优化。然后就开始对lazy进行了一个研究。

问:懒加载可以提高性能吗?

不可以简单的说"能",因为Hibernate的关系映射拖累了SQL的性能,所以想出懒加载来弥补.只是弥补而以,不会超越.所以大家不要想着使用了懒加载总体性能就提高了,其实总体性能不下降就万幸了.

问:Hibernate的lazy属性可以配置在哪里?

(常用)<set><list>标签上 ,可以取值true,false,extra默认为true,当为true时,会懒加载,访问集合属性时再发出SQL语句.但set.size()时,很不智能,不会生成count()语句,而是查出所有记录赋值给set.

extra说明:调用集合的set.size()时,会生成selectcount(*)from tableName,比较智能.建议使用

(少用)<many-to-one><one-to-one>标签上 ,可以取值false,proxy,noproxy 当为true时,会有懒加载特性,当为false时会产生N+1问题,比如一个学生对应一个班级,用一条SQL查出10个学生,当访问学生的班级属性时Hibernate会再产生10条SQL分别查出每个学生对应的班级.

(不用)<class>标签上 ,可以取值true,false 默认为true,当为false时,load()方法将失去懒加载的特性与get()一样,不影响集合(<set><list>)标签上的lazy特性

(不用)<property>标签上 ,可以取值true,false  默认值为false,懒加载某个字段,无意义,不要使用

问:get()与load()的区别

get()无懒加载特性,马上执行SQL查询.

load()有懒加载特性,会返加一个代理对象,所以永远不为null,先不执行SQL,要取对象的值时才执行SQL语句,前题session不能关闭,<class>标签上lazy不为false.

问:使用懒加载的条件

1 PO不能是final的

2能实现懒加载的对象(PO)都是被CGLIB改写的代理对象,所以不能是final修饰的

3须要asm,cglib两个jar包

4相应的lazy属性为true

5 相应的fetch属性为select

问:什么时候遇到懒加载

1 使用load()

2 一对一<one-to-one>

查主对象默认使用join连接,不会发生懒加载

查从对象默认会发生懒加载,先执行一句select查出从对象,当通过从对象访问了主对象时,再执行一句select查出主对象.

3多对一<many-to-one>

在使用hbm.xnl时,取多的一方时,默认会懒加载,不取一的一方

在使用JPA时,取多的一方时,默认自动使用joinon语句取出一的一方(用户与组,用户是多的一方,组是一的一方)

4一对多(<set><list>)

默认会懒加载,这是必须的,是重常用的。

问:实现懒加载的方案有哪些?

方法一:(没有使用懒加载)

用 Hibernate.initialize(de.getEmps()) 提前加载一下.

方法二:

把与Session脱离的对象重新绑定

lock()方法是用来让应用程序把一个未修改的对象重新关联到新session的方法。

//直接重新关联

ssion.lock(fritz,LockMode.NONE);

//进行版本检查后关联

session.lock(izi,LockMode.READ);

//使用SELECT ... FORUPDATE进行版本检查后关联

session.lock(pk,LockMode.UPGRADE);

方法三:

OpenSessionInView

OpenSessionInViewFilter是Spring提供的一个针对Hibernate的一个支持类,其主要意思是在发起一个页面请求时打开Hibernate的Session,一直保持这个Session,直到这个请求结束,具体是通过一个Filter来实现的。

由于Hibernate引入了LazyLoad特性,使得脱离Hibernate的Session周期的对象如果再想通过getter方法取到其关联对象的值,Hibernate会抛出一个LazyLoad的Exception。所以为了解决这个问题,Spring引入了这个Filter,使得Hibernate的Session的生命周期变长。

具体参考:http://www.iteye.com/topic/32001

问:fetch 和lazy 配置如何用于数据的查询

lazy 参数值常见有 false 和 true,Hibernate3 映射文件中默认lazy = true ;

fetch 指定了关联对象抓取的方式,参数值常见是select和join,默认是select,select方式先查询主对象,再根据关联外键,每一个对象发一个select查询,获取关联的对象,形成了n+1次查询;而join方式,是left outerjoin查询,主对象和关联对象用一句外键关联的sql同时查询出来,不会形成多次查询。

在映射文件中,不同的组合会使用不同的查询:

1、lazy="true" fetch = "select",使用延迟策略,开始只查询出主对象,关联对象不会查询,只有当用到的时候才会发出sql语句去查询 ;

2、lazy="false" fetch = "select",没有用延迟策略,同时查询出主对象和关联对象,产生1+n条sql.

3、lazy="true"或lazy="false" fetch ="join",延迟都不会作用,因为采用的是外连接查询,同时把主对象和关联对象都查询出来了.

另外,在hql查询中,配置文件中设置的join方式是不起作用的,而在其他查询方式如get、criteria等是有效的,使用select方式;除非在hql中指定join fetch某个关联对象。fetch策略用于get/load一个对象时,如何获取非lazy的对象/集合。这些参数在Query中无效。

最后因为前端框架使用的是easyui,绑定数据的时候,后台的数据需要转换成为json串,使用懒加载的话,级联查询数据在转换的时候就会出问题,所以UI后就把懒加载的方式舍弃了,下一节未大家介绍另一种方式优化。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-08-01 10:45:24

【java】itoo项目实战之hibernate 懒加载优化性能的相关文章

【java】itoo项目实战之hibernate 懒载入优化性能

在做itoo 3.0 的时候,考评系统想要上线,就開始导入数据了,仅仅导入学生2万条数据,可是导入的速度特别的慢.这个慢的原因是由于导入的时候进行了过多的IO操作.可是导入成功之后,查询学生的速度更加慢.由于底层用了hibernate的hql语句进行查询的,学习过hibernate的人都知道,假设hibernate不设置懒载入的话,仅仅有是有关联的数据都会一次性所有都查询出来,我试了试.查询2万条数据,最深的级联查询是有5层,然后发出来的语句是460条,时间大概是10s.然后就考虑使用lazy进

转 : Hibernate懒加载深入分析

懒加载可以提高性能吗? 不可以简单的说"能",因为hibernate的关系映射拖累了SQL的性能,所以想出懒加载来弥补.只是弥补而以,不会超越.所以大家不要想着使用了懒加载总体性能就提高了,其实总体性能不下降就万幸了.----------------------------------------------------------Hibernate的lazy属性可以配置在: (常用)<set><list>标签上 ,可以取值true,false,extra   

【转】hibernate懒加载的问题,failed to lazily initialize a collection of role

hibernate懒加载的问题,failed to lazily initialize a collection of role hibernate懒加载的问题,failed to lazily initialize a collection of role,有需要的朋友可以参考下. 今天往项目里添加了一个many-to-many的关联,发现即便是设置lazy=false也还是会报连接关闭的错误,打死都取不到数据. 可是原来有的many-to-one关联,设置了lazy=false是没问题的啊.

关于Hibernate懒加载问题的最终解决方案

看到一篇Hibernate懒加载的文章,所以转载,原地址如下: http://tuoxie007.iteye.com/blog/334853 Hibernate的强大之处之一是懒加载功能,可以有效的降低数据库访问次数和内存使用量.但用的不好就会出现org.hibernate.LazyInitializationException. 这个异常出现的原因很简单,主要时在加载懒数据时Session已经关闭造成的. 那么OK,我们来考虑怎么解决吧. 我们只要在渲染JSP之前不要关闭Session,而在J

调查管理系统 -(6)自定义Struts2的拦截器&amp;自定义UserAware接口&amp;Action中模型赋值问题&amp;Hibernate懒加载问题

1.对于一些功能,如我的调查或新建调查等,只有用户登录后才能进行操作,因此必须对用户是否登录进行判断.当用户登录后才能使用相应的功能,如果没有登录则需为用户导航到登录页面让其进行登录.这个功能可以通过自定义Struts2的拦截器来完成. 2.当用户登录之后,由于是将用户的信息保存在session中的.这样当一些Action中需要用到当前登录的用户的信息时需要手动的从session中获取,不太方便,因此我们声明了一个UserAware接口(即用户关注,类似于Struts2中的SessionAwar

hibernate懒加载

16.懒加载 性能: 发出的sql语句越少,性能越高 方法: 1.懒加载 2.抓取策略 3.缓存策略 4.HQL语句   懒加载 1.类的懒加载 1.利用session.load方法可以产生代理对象 2.在session.load方法执行的时候并不发出sql语句 3.在得到其一般属性的时候发出sql语句 4.只针对一般属性有效,针对标示符属性是无效的 5.默认情况就是懒加载  2.集合的懒加载 <set name=""  lazy="" cascasd=&qu

hibernate懒加载(转载)

http://blog.csdn.net/sanjy523892105/article/details/7071139 懒加载详解 懒加载为Hibernate中比较常用的特性之一,下面我们详细来了解下懒加载的原理和注意事项 Load()方法的懒加载原理 在Hibernate中,查询方法有两个,分别是get()和load(),这两种方法的不同就是load()拥有懒加载的特性.Load()方法就是在查询某一条数据的时候并不会直接将这条数据以指定对象的形式来返回,而是在你真正需要使用该对象里面的一些属

关于s2sh框架关于hibernate懒加载问题的说明和解决方案

首先我们来看下面这个图,解释了一个web程序的一次请求流程! 懒加载异常的说明: 懒加载就是我们在查询一个对象时,它所有的属性是否要被查出来! 如果懒加载开启的话,session在service层就被关闭了,而我们的view如果不需要他的属性的话,那就不会出现懒加载异常,如果需要属性,这时候session已经关闭了所以就会出现懒加载异常,这个时候我们就考虑能否把session放到请求完成之后再进行关闭. 解决: 答案当然是可以,那就是使用过滤器,在请求结束之后将session关闭,在web.xm

Hibernate懒加载解析(转)

在Hibernate框架中,当我们要访问的数据量过大时,明显用缓存不太合适, 因为内存容量有限 ,为了减少并发量,减少系统资源的消耗,这时Hibernate用懒加载机制来弥补这种缺陷,但是这只是弥补而不是用了懒加载总体性能就提高了. 我们所说的懒加载也被称为延迟加载,它在查询的时候不会立刻访问数据库,而是返回代理对象,当真正去使用对象的时候才会访问数据库. 实现懒加载的前提: 1 实体类不能是final的 2 能实现懒加载的对象都是被CGLIB(反射调用)改写的代理对象,所以不能是final修饰