Hibernate 二级缓存 以及 HibernateDaoSupport 简单总结

来源:互联网 发布:菜刀选取 知乎 编辑:程序博客网 时间:2024/05/17 08:38

好久没用到这类的东西。最近领导要搞下hibernate的二级缓存。所以着手搞了一下 根据网上的资料与自己的实际分析。


首先我不知道用缓存以后能对系统提高多高的效率。我没搞过互联网项目,也不知道这对性能有多大的影响。只是从资料分析来看

一般来说针对很少被修改以及不是很重要的数据才用到缓存,我们做的是电子商务的网站,所以就我个人认为像一些产品信息

应该在用户并发的时候应该很少会被更改,而像购物车,订单,之类的可能会被频繁操作。所以关于订单和购物车之类的不进行缓存

而且其他的读取产品信息的东西进行缓存。但是这里还有一点,缓存针对 get,load的的时候可能效率会高,针对查询的时候究竟

命中率有多高真不知道会给效率提高多少也没有人给我一个答案,希望有这方面经验的人可以和我探讨一下。


1.hibernate二级缓存的策略:
条件查询的时候,总是发出一条select * from table_name 这样的查询获取所有数据。
2.把获得的所有数据对象根据id放入二级缓存
3.当根据id访问数据的时候首先从session一级缓存查,查不到二级缓存查,二级缓存查不到再查
库。
4.delete update insert的时候同时更新缓存。
二级缓存针对id查询的缓存策略,对条件查询毫无作用。hibernate专门提供了query cache。所以如果进行了操作比较频繁的数据还是别用缓存。



下面就是我在项目中 spring+hibernate环境下配置的二级缓存。

首先在applicationContext.xml的配置文件中的

<property name="hibernateProperty"></property>中添加如下属性

<!-- 设置二级缓存插件为EHCACHE --><prop key="hibernate.cache.provider_class">                     org.hibernate.cache.EhCacheProvider                 </prop>                 <!-- 开启使用二级缓存 -->                 <prop key="hibernate.cache.use_second_level_cache">true</prop>                 <!-- 使用查询缓存  如果不设置“查询缓存”,那么hibernate只会缓存使用load()方法获得的单个持久化对象,                如果想缓存使用findall()、 list()、Iterator()、createCriteria()、createQuery()等方法获得的数据结果集的话,                就需要设置hibernate.cache.use_query_cache true 才行-->                 <prop key="hibernate.cache.use_query_cache">true</prop> 
如图

我这里用的是EhCache这个缓存插件。配置好这步以后建立ehcache.xml默认路径在classpath下。

内容为:

<!-- 
defaultCache节点为缺省的缓存策略
maxElementsInMemory 内存中最大允许存在的对象数量
eternal 设置缓存中的对象是否永远不过期
overflowToDisk 如果为true 把溢出的对象存放到硬盘上(当对象达到1000个的时候,是否会把溢出的【比如1001个】放到硬盘上去)
timeToIdleSeconds 指定缓存对象空闲多长时间就过期,过期的对象会被清除掉
timeToLiveSeconds 指定缓存对象总的存活时间
diskPersistent 当jvm结束是是否持久化对象(当缓存应用关闭的时候是否要把缓存的对象持久化到磁盘上去?)
diskExpiryThreadIntervalSeconds 指定专门用于清除过期对象的监听线程的轮询时间

<diskStore> 设置缓存数据文件的存放目录
<defaultCache> 设置缓存的默认数据过期策略
 -->

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd">   <diskStore path="java.io.tmpdir"/>   <!--defaultCache 定义缓存的一些默认行为--><defaultCache maxElementsInMemory="10000" eternal="false"overflowToDisk="false" timeToIdleSeconds="300" timeToLiveSeconds="600"/></ehcache>

此处有多中配置方式,同时还可以将你需要个性设置的hbm的缓存策略配置上,因为我没有此独特的需求,所以就用默认的方式


然后在相应的hbm的隐射文件中,加入如下代码:

<cache usage="read-write"/> 
如图:

hibernate二级缓存策略:
transactional,read-write,nonstrict-read-write,read-only
read-only:只读缓存,读取一个持久化的实例,而无需对其修改。
read-write:读写缓存,在集群环境中使用此策略,必须保证底层的缓存实现支持锁定。
nonstrict-read-write 非严格读写缓存,如果两个事务同时更新同一记录的情况很不常见,
也不需要十分严格的事务隔离,那么比较合适用非严格读写缓存
transactional事务缓存,hibernate的事务缓存策略提供了全事务的缓存支持。

至此已经基本告一段落。只剩下最后的工作。

如图:



其中那个bean是我们的dao配置。基本做过开发就知道这段是什么意思了。

记得要有cacheQueries的set方法


配置完毕以后,我们要如何才能确定是否已经应用上了缓存呢。还需要log4j即可

#log4j.logger.org.hibernate=debug
log4j.logger.org.hibernate=error
log4j.category.net.sf.ehcache=debug



基本用了hibernate和spring的就一定会用到hibernateDaoSupport。一般的情况下,此中得find方法不会

查询缓存,需要加入如下代码才会查询缓存

getHibernateTemplate().setCacheQueries(cacheQueries);

好了。到此为止hibernate二级缓存的配置算是完成了。但是具体能提高多少效率以及后继的问题就等出现大家一起探讨了。



配置二级缓存的过程当初发现了一点关于 HibernateDaoSupport的问题。下面说一下这个问题,一是给自己个记忆,二是给后来人点提示

一般来说使用hibernateDaoSupport的时候有几种配置方式:

1.dao继承自hibernateDaoSupport,将sessionFactory注入到dao中这样就可以用了。但是这样做的一个弊端就是在xml中需要配置N多的

dao很麻烦,简单的例子就是初期的时候没有用缓存,后期加入缓存,修改配置文件的时候就会很麻烦。

2.这种方法相对于第一种比较简单一点,在外层做一层包装,就是bean中定义一个hibernateTemplate然后将sessionFactory注入到这个hibernateTemplate

然后将这个hibernatetemplate注入到想用的dao中,这样修改起来相对于第一种稍微简单了一点。

3.方法是在第二层基础上有一个basedao。此basedao extends daosupport。然后给此中注入sessionfactory。然后以后其他的dao都继承此basedao。然后在

xml中配置的时候只需要声明dao然后extends basedao即可。这样就方便快捷了。

如图:


是不是方便了一点。


好了暂时到此为止,希望有同道中人可以一起探讨 进步。