Hibernate二级缓存(转)

这两天优化一个模块,那模块的问题是有时用户量访问量大时就慢了,于是想起去优化数据库操作,使用Hibernate的二级缓存。 
先是看了一些参考手册,然后找了几个配置的实例,测试成功。对二级缓存有了更多的认识。 
缓存本质上来说就是HashMap,一个ID对应一个Value,暂时放入内在或者硬盘,用的时候先从缓存里面取,若没有再去数据库取。避免缓存出现赃数据和缓存的命中率是一对死对头,若想命中效高,则存在的有效时间就得长,但这样却容易出现赃数据,因为更新的时间间隔长了。所以难点就在去找到一个平衡点,一个最优最能接受的点。 

Hibernate是对JDBC的轻型封装,要想做到像JDBC那样轻便、快捷,就需要比较优化的配置。Hibernate一级缓存是做在session层上的;而二级缓存则做在sessionFactory,所以session共享。 

下面先介绍下Hibernate的二级缓存(来自中文参考手册),然后介绍其配置。 

1、二级缓存(The Second Level Cache) 
Hibernate的Session在事务级别进行持久化数据的缓存操作。 当然,也有可能分别为每个类(或集合),配置集群、或JVM级别(SessionFactory级别)的缓存。 你甚至可以为之插入一个集群的缓存。注意,缓存永远不知道其他应用程序对持久化仓库(数据库)可能进行的修改 (即使可以将缓存数据设定为定期失效)。 

通过在hibernate.cache.provider_class属性中指定org.hibernate.cache.CacheProvider的某个实现的类名,你可以选择让Hibernate使用哪个缓存实现。Hibernate打包一些开源缓存实现,提供对它们的内置支持(见下表)。除此之外,你也可以实现你自己的实现,将它们插入到系统中。注意,在3.2版本之前,默认使用EhCache 作为缓存实现,但从3.2起就不再这样了。 

表 1.  缓存策略提供商(Cache Providers) 

CacheProvider classTypeCluster SafeQuery Cache Supported
 
Hashtable (not intended for production use)org.hibernate.cache.HashtableCacheProvidermemory  yes
 
EHCacheorg.hibernate.cache.EhCacheProvidermemory, disk  yes
 
OSCacheorg.hibernate.cache.OSCacheProvidermemory, disk  yes
 
SwarmCacheorg.hibernate.cache.SwarmCacheProviderclustered (ip multicast)yes (clustered invalidation)  
 
JBossTreeCache org.hibernate.cache.TreeCacheProviderclustered (ip multicast), transactionalyes (replication)yes (clock sync req.)




2、缓存映射(Cache mappings) 
类或者集合映射的“<cache>元素”可以有下列形式: 

Java代码 
  1. <cache   
  2.     usage="transactional|read-write|nonstrict-read-write|read-only"  
  3.     region="RegionName"  
  4.     include="all|non-lazy"  
  5. />  

usage(必须)说明了缓存的策略: transactional、 read-write、 nonstrict-read-write或 read-only。 

region (可选, 默认为类或者集合的名字(class or collection role name)) 指定第二级缓存的区域名(name of the second level cache region) 

include (可选,默认为 all) non-lazy 当属性级延迟抓取打开时, 标记为lazy="true"的实体的属性可能无法被缓存 


另外(首选?), 你可以在hibernate.cfg.xml中指定<class-cache>和 <collection-cache> 元素。 

这里的usage 属性指明了缓存并发策略(cache concurrency strategy)。 

3、策略:只读缓存(Strategy: read only) 
如果你的应用程序只需读取一个持久化类的实例,而无需对其修改, 那么就可以对其进行只读 缓存。这是最简单,也是实用性最好的方法。甚至在集群中,它也能完美地运作。 

Java代码 
  1. <class name="eg.Immutable" mutable="false">  
  2.     <cache usage="read-only"/>  
  3.     ....  
  4. </class>  

19.2.3.  策略:读/写缓存(Strategy: read/write) 
如果应用程序需要更新数据,那么使用读/写缓存 比较合适。 如果应用程序要求“序列化事务”的隔离级别(serializable transaction isolation level),那么就决不能使用这种缓存策略。 如果在JTA环境中使用缓存,你必须指定hibernate.transaction.manager_lookup_class属性的值, 通过它,Hibernate才能知道该应用程序中JTA的TransactionManager的具体策略。 在其它环境中,你必须保证在Session.close()、或Session.disconnect()调用前, 整个事务已经结束。 如果你想在集群环境中使用此策略,你必须保证底层的缓存实现支持锁定(locking)。Hibernate内置的缓存策略并不支持锁定功能。 

Java代码 
  1. <class name="eg.Cat" .... >  
  2.     <cache usage="read-write"/>  
  3.     ....  
  4.     <set name="kittens" ... >  
  5.         <cache usage="read-write"/>  
  6.         ....  
  7.     </set>  
  8. </class>  

4、策略:非严格读/写缓存(Strategy: nonstrict read/write) 
如果应用程序只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离, 那么比较适合使用非严格读/写缓存策略。如果在JTA环境中使用该策略, 你必须为其指定hibernate.transaction.manager_lookup_class属性的值, 在其它环境中,你必须保证在Session.close()、或Session.disconnect()调用前, 整个事务已经结束。 

5、 策略:事务缓存(transactional) 
Hibernate的事务缓存策略提供了全事务的缓存支持, 例如对JBoss TreeCache的支持。这样的缓存只能用于JTA环境中,你必须指定 为其hibernate.transaction.manager_lookup_class属性。 

没有一种缓存提供商能够支持上列的所有缓存并发策略。下表中列出了各种提供器、及其各自适用的并发策略。 

表 2.  各种缓存提供商对缓存并发策略的支持情况(Cache Concurrency Strategy Support) 

Cacheread-onlynonstrict-read-writeread-writetransactional
 
Hashtable (not intended for production use)yesyesyes 
 
EHCacheyesyesyes  
 
OSCacheyesyesyes 
 
SwarmCacheyesyes   
 
JBoss TreeCacheyes  yes





二级缓存配置:    
   
1、首先要打开二级缓存,在hibernate.cfg.xml中添加如下配置:    
<property name="hibernate.cache.use_second_level_cache">true</property>   
   
2、Hibernate的二级缓存使用第三方的缓存工具来实现,所以我们需要指定Hibernate使用哪个缓存工具。如下配置指定Hibernate使用EhCache缓存工具。    
<property name="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</property>   
   
3、Hibernate在默认情况下并不会对所有实体对象进行缓存,所以,我们需要指定缓存哪些对象,在实体对象的映射文件中(相应的<class>标签内部),添加如下配置:    
<cache usage="read-only"/>   
   
usage="read-only"是“只读”缓存策略。    
   
注意,这个<cache>标签只能放在<class>标签的内部,而且必须处在<id>标签的前面!!!这个<cache>标签放在哪些<class>标签下面,就说明会多这些类的对象进行缓存 
(缓存策略既可放到hibernate.cfg.xml中,也可放到对应实体的映射文件中)    
   
4、对于第3步,有一个可选的方案是在hibernate.cfg.xml文件中指定哪些类的对象需要缓存,而不需要使用<cache>标签来指定。如:   
   在hibernate.cfg.xml中添加如下配置:    
   <class-cache class="com.bjsxt.hibernate.Classes" usage="read-only" />   
      
   注意,这个<class-cache>标签必须放在<mapping>标签的后面!!   

1、首先设置EhCache,建立配置文件ehcache.xml,默认的位置在class-path,可以放到你的src目录下: 

Java代码 
  1. <?xml version="1.0" encoding="UTF-8"?>   
  2. <ehcache>   
  3.  <diskStore path="java.io.tmpdir"/>   
  4.   <defaultCache   
  5.    maxElementsInMemory="10000" <!-- 缓存最大数目 -->   
  6.    eternal="false" <!-- 缓存是否持久 -->   
  7.    overflowToDisk="true" <!-- 是否保存到磁盘,当系统当机时-->   
  8.    timeToIdleSeconds="300" <!-- 当缓存闲置n秒后销毁 -->   
  9.    timeToLiveSeconds="180" <!-- 当缓存存活n秒后销毁-->   
  10.    diskPersistent="false"   
  11.    diskExpiryThreadIntervalSeconds= "120"/>   
  12. </ehcache>   


  2、在Hibernate配置文件中设置: 

Java代码 
  1. <!-- 设置Hibernate的缓存接口类,这个类在Hibernate包中 -->   
  2. <property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>   
  3.  <!-- 是否使用查询缓存 -->   
  4.  <property name="hibernate.cache.use_query_cache"true</property>   
  5.   如果使用spring调用Hibernate的sessionFactory的话,这样设置:   
  6.   <!--HibernateSession工厂管理 -->   
  7.    <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">   
  8.    <property name="dataSource">   
  9.     <ref bean="datasource" />   
  10.    </property>   
  11.    <property name="hibernateProperties">   
  12.    <props>   
  13.     <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop>   
  14.     <prop key="connection.provider_class">org.hibernate.connection.C3P0ConnectionProvider</prop>   
  15.     <prop key="hibernate.show_sql"true</prop>   
  16.     <prop key="hibernate.cache.use_query_cache"true</prop>   
  17.     <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>   
  18.    </props>   
  19.  </property>   
  20.  <property name="mappingDirectoryLocations">   
  21.   <list>   
  22.    <value>/WEB-INF/classes/cn/rmic/manager/hibernate/</value>   
  23.   </list>   
  24.  </property>   
  25. </bean>   

  说明一下:如果不设置“查询缓存”,那么hibernate只会缓存使用load()方法获得的单个持久化对象,如果想缓存使用 findall()、list()、Iterator()、createCriteria()、createQuery()等方法获得的数据结果集的话,就需要设置 
hibernate.cache.use_query_cache true 才行 

  3、在Hbm文件中添加<cache usage="read-only"/> 

  4、如果需要“查询缓存”,还需要在使用Query或Criteria()时设置其setCacheable(true);属性 

  5、只有自己动手才知道,自己写一段简单的测试程序(两次查询),如果成功的话第二次查询时不会读取数据库(设置成让Hibernate显示sql语句,方便看结果)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值