Hibernate 利用缓存(一级、二级、查询)提高系统性能(二)

2014-11-23 17:40:20 · 作者: · 浏览: 36
fetch 只对 HQL 查询产生影响其他的则不会


OpenSessionInview问题

这个问题出现是由于load()懒加载导致的,第一次查询数据时使用了懒加载至查询出来数据的ID,当使用数据的时候还需要去数据库里面查询但是此时数据库的session已经关闭,解决此问题两种思路一种是不使用懒加载;其二是在web层开发关闭session,延长session的生命周期。


二级缓存


二级缓存也称为进程级缓存或sessionFactory缓存,也可以叫做集群范围内的缓存,需要第三方来实现,hibernate默认的二级缓存插件为ehcache这个缓存,由于二级缓存是进程级的可能出现多线程并发问题,需要设置缓存的并发策略。

hibernate二级缓存需要第三方插件支持,hibernate默认支持为ehcache关于配置请参考:Spring AOP +EHcache为Service层方法增加缓存


开启二级缓存后对方法的影响

get()/load()

对于这两个方法没啥影响,第一次从数据库里面查询,第二次先判断缓存里面有没有数据如果没有再去数据库里面查询。


查询缓存


查询缓存是针对普通属性结果集的缓存,不缓存实体对象,当和查询缓存关联的表发生修改的时候,查询缓存生命周期结束,里面的数据也随即被清空了。

查询缓存的配置和使用:
List方法读写查询缓存,Iterator不使用查询缓存(查询缓存只对query.list()有效)

查询缓存的配置,默认不开启hibernate3配置:

	  	
  
   org.hibernate.cache.NoCacheProvider
  
	  	
  
   false
   
	        
  
   true
    

代码中,加上一句话
query.setCacheable(true)


一级、二级、查询之间的关系


一级缓存总是开启状态,我们需要关注的是查询缓存和二级缓存,查询缓存可以只开启一个或者两个都打开。
开启二级缓存时,如果两个session先后执行load或者get方法,只执行一条语句第二次会从缓存中查找,先从一级缓存中查询,如果没有再去二级缓存中查找。

一级缓存同二级缓存交互

禁止一级缓存与二级缓存交互,如下设置

session.setCacheMode(CacheMode.IGNORE);
打开一个session执行查询,它会先将查询结果保存到一级缓存,待session关闭后,一级缓存中数据清空,由于禁止了一级缓存同二级缓存数据交互,因此,一级缓存关闭后不会将结构保存到二级缓存,打开第二个session后,后再发送一条查询语句,因此二级缓存中没有数据。


查询缓存与二级缓存


开启查询,关闭二级
如果两次执行query.list(),第一次发送查询语句会将结果对象的id保存到查询缓存中,第二次会先从查询缓存中取出ID,根据id先去一级缓存查找,再二级缓存,如果没有找到会去数据库中查找,一级缓存同session没有关系,只和表有关系。

开启查询,开启二级缓存

两次执行query.list(),第一次发送查询语句将结果


总结:

缓存在一个项目中对于提高系统性能很重要,除了ehcache之外还有memcache、redis等缓存产品目前都很常用,redis具有丰富的数据类型以及单线程高效能访问效率,memcache虽然是多线程但效率还是没有redis高。

这些缓存产品都可以实现分布式缓存,ehcache+rmi可以分布式缓存同步;memcache+redis都支持分布式,redis还提供了高可用性的解决方案:主从复制几个服务器直接爱你可以切换。