您的位置:首页 > 其它

Hibernate性能优化策略(一)

2012-07-30 08:36 387 查看
在Hibernate系列文章的第一篇中就提到了使用Hibernate会有一个性能问题,但万事不是绝对的,总会有办法,下面的几个方法虽不能彻底解决性能的问题,但基本上也能满足大多数的需求。
抓取策略
单端代理
a)         保持默认,同fetch="select",如:<many-to-onename="classes"
column="classesid"fetch="select"/>,fetch="select",另外发送一条select语句加载当前对象的关联对象或集合。
b)        设置fetch="join",如:<many-to-onename="classes"
column="classesid"fetch="join"/>,hibernate会通过一个select语句连接(内联/外联:取决于外键是否为空)抓取其关联对象或集合,lazy失效,fetch为select或join不影响hql查询,它影响的是load,get方法。
<many-to-one>可能会出现N+1问题,如:查询100个学生显示到列表中:首先会发出查询学生的sql语句,然后会发出根据班级id查询班级的sql语句,这样就会导致N+1问题,也就是发出了N+1条语句,会严重影响性能,所以我们可以采用预先抓取的策略,如:selects
from Student s join fetch s.classes。
集合代理
a)         保持默认,同fetch="select",如:<setname="students"
order-by="id" inverse="true"cascade="all" fetch="select">,fetch="select",另外发送一条select语句加载当前对象的关联对象或集合。
b)        设置fetch="join",如:<setname="students"
order-by="id" inverse="true"cascade="all" fetch="join">,hibernate会通过一个select语句连接(内联/外联)抓取其关联对象或集合,fetch="join",那么lazy失效,fetch="join",只影响get和load,对hql没有影响。
c)         设置fetch="subselect",如:<setname="students"
order-by="id" inverse="true"cascade="all" fetch="subselect">,另外发送一条select语句抓取在前面查询到的所有实体的关联集合,fetch="subselect",会影响hql查询。
批量抓取
batch-size属性,可以批量加载实体类,参见参见Classes.hbm.xml中的配置:
 <classname="com.bjpowernode.hibernate.Classes"table="t_classes" batch-size="10">,batch-size属性就是为了减少发出的sql语句量。
Lazy加载机制
Lazy是延迟加载,只有真正使用该对象时,才会创建,对于Hibernate来说,只有真正使用时才会发出sql,这样可以提高一些性能。Hibernate的lazyloading采用了一个HibernateSession来管理session,他的逻辑是每进行一次数据库操作,就开新的session,操作完成后立即关闭该session,这样做的好处是可以严格关闭session,但不适合跨方法的事务。
Class标签上的Lazy
<class>标签上,可以取值:true/false,它只影响普通属性。查id不发sql,因为传的就是主键,查别的属性会发sql,HibernateLazy有效期必须是session在open时才可以,解决方式是使用openSessionInview(后面的Spring会有讲解)。
集合标签上的Lazy
<set>/<list>标签上,可以取值:true/false/extra。<class>标签上的lazy不会影响集合上的lazy特性,把class标签上的lazy设置成false时,再load类时会把普通属性都查出来,但是集合不查。
get集合时不会发sql,迭代会发sql,查个数的时候会把整个集合查出来,这样对效率有影响,lazy在集合上用extra获取size的时候会发出count语句,对效率有所提升。
单端关联上的Lazy
<many-to-one>/<one-to-one>单端关联标签上,可以取值:false/proxy/noproxy。<class>标签上的lazy不会影响单端关联对象的lazy策略。单端关联上的lazy和集合一样,在get时返回代理不发查询语句,使用时发出sql。在单端关联上lazy=false,在访问普通属性时发出两条sql,查询属性以及对应的关联对象。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: