首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > 编程 >

Hibernate性能优化对策(一)

2012-09-12 
Hibernate性能优化策略(一)在Hibernate系列文章的第一篇中就提到了使用Hibernate会有一个性能问题,但万事

Hibernate性能优化策略(一)

在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,查询属性以及对应的关联对象。

2楼xiaokui008昨天 09:30
学习
Re: StubbornPotatoes12小时前
回复xiaokui008n[e01]
1楼lfmilaoshi昨天 08:52
刚刚开始。。。米老师

热点排行