Hibernate性能优化策略(一)

本文介绍Hibernate框架中的性能问题及解决方案,包括抓取策略、批量抓取、Lazy加载机制等,并详细解释了各种配置选项及其对性能的影响。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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失效,fetchselectjoin不影响hql查询,它影响的是loadget方法。

<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",只影响getload,对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,这样可以提高一些性能。Hibernatelazyloading采用了一个HibernateSession来管理session,他的逻辑是每进行一次数据库操作,就开新的session,操作完成后立即关闭该session,这样做的好处是可以严格关闭session,但不适合跨方法的事务。

Class标签上的Lazy

<class>标签上,可以取值:true/false,它只影响普通属性。查id不发sql,因为传的就是主键,查别的属性会发sqlHibernateLazy有效期必须是sessionopen时才可以,解决方式是使用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,查询属性以及对应的关联对象。

评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值