Hibernate ehcache配置二级缓存 Love The Way You Lie 2022-08-02 10:52 101阅读 0赞 1、首先设置EhCache,建立配置文件ehcache.xml,默认的位置在class-path,可以放到你的src目录下: <?xml version="1.0" encoding="UTF-8"?> <ehcache> <diskStore path="java.io.tmpdir"/> <defaultCache maxElementsInMemory="10000"<!-- 缓存最大数目 --> eternal="false"<!-- 缓存是否持久 --> overflowToDisk="true"<!-- 是否保存到磁盘,当系统当机时--> timeToIdleSeconds="300"<!-- 当缓存闲置n秒后销毁 --> timeToLiveSeconds="180"<!-- 当缓存存活n秒后销毁--> diskPersistent="false" diskExpiryThreadIntervalSeconds= "120"/> </ehcache> 2、在Hibernate配置文件中设置: <!-- 设置Hibernate的缓存接口类,这个类在Hibernate包中 --> <property name="cache.provider\_class">org.hibernate.cache.EhCacheProvider</property> <!-- 是否使用查询缓存 --> <property name="hibernate.cache.use\_query\_cache">true</property> 如果使用spring调用Hibernate的sessionFactory的话,这样设置: <!--HibernateSession工厂管理 --> <bean id="sessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="datasource" /> </property> <property name="hibernateProperties"> <props> <prop key="hibernate.dialect">org.hibernate.dialect.Oracle9Dialect</prop> <prop key="connection.provider\_class">org.hibernate.connection.C3P0ConnectionProvider</prop> <prop key="hibernate.show\_sql">true</prop> <prop key="hibernate.cache.use\_query\_cache">true</prop> <prop key="hibernate.cache.provider\_class">org.hibernate.cache.EhCacheProvider</prop> </props> </property> <property name="mappingDirectoryLocations"> <list> <value>/WEB-INF/classes/cn/rmic/manager/hibernate/</value> </list> </property> </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、实践出真知,给一段测试程序,如果成功的话第二次查询时不会读取数据库 package cn.rmic.hibernatesample; import java.util.List; import org.hibernate.CacheMode; import org.hibernate.Criteria; import org.hibernate.Query; import org.hibernate.Session; import cn.rmic.hibernatesample.hibernate.HibernateSessionFactory; import cn.rmic.manager.po.Resources; public class testCacheSelectList ...\{ public static void main(String\[\] args) ...\{ Session s=HibernateSessionFactory.getSession(); Criteria c=s.createCriteria(Resources.class); c.setCacheable(true); List l=c.list(); Resources resources=(Resources)l.get(0); System.out.println("-1-"+resources.getName()); HibernateSessionFactory.closeSession(); try ...\{ Thread.sleep(5000); \} catch (InterruptedException e) ...\{ // TODO Auto-generated catch block e.printStackTrace(); \} s=HibernateSessionFactory.getSession(); c=s.createCriteria(Resources.class); c.setCacheable(true); l=c.list(); resources=(Resources)l.get(0); System.out.println("-2-"+resources.getName()); HibernateSessionFactory.closeSession(); \} \} 1. 在Hibernate配置文件中设置: ![None.gif][] <!-- Hibernate SessionFactory \--> ![None.gif][] < bean id = " sessionFactory " class = " org.springframework.orm.hibernate3.LocalSessionFactoryBean " > ![None.gif][] < property name = " dataSource " ref = " dataSource " /> ![None.gif][] < property name = " mappingResources " > ![None.gif][] < list > ![None.gif][] < value > com / ouou / model / Videos.hbm.xml </ value > ![None.gif][] </ list > ![None.gif][] </ property > ![None.gif][] < property name = " hibernateProperties " > ![None.gif][] < props > ![None.gif][] < prop key = " hibernate.dialect " > org.hibernate.dialect.MySQLDialect </ prop > ![None.gif][] < prop key = " hibernate.current\_session\_context\_class " > thread </ prop > ![None.gif][] < prop key = " hibernate.cglib.use\_reflection\_optimizer " > false </ prop > ![None.gif][] < prop key = " hibernate.query.substitutions " > true ' Y ' , false ' N ' </ prop > ![None.gif][] <!-- add ehcache \--> ![None.gif][] < prop key = " hibernate.cache.provider\_class " > org.hibernate.cache.EhCacheProvider </ prop > ![None.gif][] < prop key = " hibernate.cache.use\_query\_cache " > false </ prop ><!-- 是否使用查询缓存 \--> ![None.gif][] <!-- ![None.gif][] < prop key = " hibernate.cache.provider\_configuration\_file\_resource\_path " >/ ehcache.xml </ prop > ![None.gif][] < prop key = " hibernate.show\_sql " > true </ prop > ![None.gif][] \--> ![None.gif][] <!--< prop key = " hibernate.transaction.auto\_close\_session " > true </ prop >--> ![None.gif][] < prop key = " connection.provider\_class " > org.hibernate.connection.C3P0ConnectionProvider </ prop > ![None.gif][] <!-- Create / update the database tables automatically when the JVM starts up ![None.gif][] < prop key = " hibernate.hbm2ddl.auto " > update </ prop > \--> ![None.gif][] <!-- Turn batching off for better error messages under PostgreSQL \--> ![None.gif][] < prop key = " hibernate.jdbc.batch\_size " > 25 </ prop > ![None.gif][] <!-- ![None.gif][] < prop key = " hibernate.connection.pool\_size " > 10 </ prop > ![None.gif][] \--> ![None.gif][] </ props > ![None.gif][] </ property > ![None.gif][] </ bean > 如果不设置“查询缓存”,那么hibernate只会缓存使用load()方法获得的单个持久化对象,如果想缓存使用findall()、 list()、Iterator()、createCriteria()、createQuery()等方法获得的数据结果集的话,就需要设置 hibernate.cache.use\_query\_cache true 才行 2.首先设置EhCache,建立配置文件ehcache.xml,默认的位置在class-path,可以放到你的src目录下: ![None.gif][] < ehcache > ![None.gif][] ![None.gif][] <!-- Sets the path to the directory where cache .data files are created. ![None.gif][] ![None.gif][] If the path is a Java System Property it is replaced by ![None.gif][] its value in the running VM. ![None.gif][] The following properties are translated: ![None.gif][] user.home \- User ' s home directory ![None.gif][] user.dir \- User ' s current working directory ![None.gif][] java.io.tmpdir \- Default temp file path \--> ![None.gif][] <!--< diskStore path = " java.io.tmpdir " />--> ![None.gif][] < diskStore path = " /data/ehcache " /> ![None.gif][] ![None.gif][] <!-- Default Cache configuration. These will applied to caches programmatically created through ![None.gif][] the CacheManager. ![None.gif][] ![None.gif][] The following attributes are required: ![None.gif][] ![None.gif][] maxElementsInMemory \- Sets the maximum number of objects that will be created in memory ![None.gif][] eternal \- Sets whether elements are eternal. If eternal, timeouts are ![None.gif][] ignored and the element is never expired. ![None.gif][] overflowToDisk \- Sets whether elements can overflow to disk when the in \- memory cache ![None.gif][] has reached the maxInMemory limit. ![None.gif][] ![None.gif][] The following attributes are optional: ![None.gif][] timeToIdleSeconds \- Sets the time to idle for an element before it expires. ![None.gif][] i.e. The maximum amount of time between accesses before an ![None.gif][] element expires Is only used if the element is not eternal. ![None.gif][] Optional attribute. A value of 0 means that an Element can idle ![None.gif][] for infinity.The default value is 0 . ![None.gif][] timeToLiveSeconds \- Sets the time to live for an element before it expires. ![None.gif][] i.e. The maximum time between creation time and when an element ![None.gif][] expires. Is only used if the element is not eternal. ![None.gif][] Optional attribute. A value of 0 means that and Element can live ![None.gif][] for infinity. ![None.gif][] The default value is 0 . ![None.gif][] diskPersistent \- Whether the disk store persists between restarts of the Virtual Machine. ![None.gif][] The default value is false . ![None.gif][] diskExpiryThreadIntervalSeconds \- The number of seconds between runs of the disk expiry thread. ![None.gif][] The default value is 120 seconds. ![None.gif][] \--> ![None.gif][] ![None.gif][] < defaultCache ![None.gif][] maxElementsInMemory = " 10000 " ![None.gif][] eternal = " false " ![None.gif][] overflowToDisk = " true " ![None.gif][] timeToIdleSeconds = " 120 " ![None.gif][] timeToLiveSeconds = " 120 " ![None.gif][] diskPersistent = " false " ![None.gif][] diskExpiryThreadIntervalSeconds = " 120 " /> ![None.gif][] < cache name = " org.hibernate.cache.UpdateTimestampsCache " maxElementsInMemory = " 5000 " ![None.gif][] eternal = " true " overflowToDisk = " true " /> ![None.gif][] < cache name = " org.hibernate.cache.StandardQueryCache " maxElementsInMemory = " 5 " eternal = " false " ![None.gif][] timeToLiveSeconds = " 120 " overflowToDisk = " true " /> ![None.gif][] < cache name = " userCache " maxElementsInMemory = " 100000 " eternal = " false " timeToIdleSeconds = " 600 " timeToLiveSeconds = " 600 " overflowToDisk = " false " diskPersistent = " false " /> ![None.gif][] < cache name = " com.ouou.webapp.util.OuouMethodIntecepter " maxElementsInMemory = " 100000 " ![None.gif][] eternal = " false " timeToIdleSeconds = " 600 " timeToLiveSeconds = " 600 " overflowToDisk = " false " ![None.gif][] diskPersistent = " false " /> ![None.gif][] < cache name = " bbcode " maxElementsInMemory = " 100000 " eternal = " false " timeToIdleSeconds = " 600 " ![None.gif][] timeToLiveSeconds = " 600 " ![None.gif][] overflowToDisk = " false " diskPersistent = " false " /> ![None.gif][] < cache name = " com.ouou.model.Videos " maxElementsInMemory = " 10000 " eternal = " false " ![None.gif][] overflowToDisk = " false " timeToIdleSeconds = " 120 " timeToLiveSeconds = " 120 " diskPersistent = " false " /> ![None.gif][] < cache name = " com.ouou.model.Tags " maxElementsInMemory = " 10000 " eternal = " false " ![None.gif][] overflowToDisk = " false " timeToIdleSeconds = " 120 " timeToLiveSeconds = " 120 " diskPersistent = " false " /> ![None.gif][] </ ehcache > 以com.ouou.model.Videos为例子 在Videos.hbm.xml中配置: <class name="Videos" table="TEST" lazy="false"> <cache usage="read-write" region="ehcache.xml中的name的属性值"/>注意:这一句需要紧跟在class标签下面,其他位置无效。 hbm文件查找cache方法名的策略:如果不指定hbm文件中的region="ehcache.xml中的name的属性值",则使用name名为com.ouou.model.Videos的cache, 如果不存在与类名匹配的cache名称,则用defaultCache。 如果Videos包含set集合,则需要另行指定其cache 例如Videos包含Tags集合,则需要 添加如下配置到ehcache.xml中 <cache name="com.ouou.model.Tags" maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="false" /> 另,针对查询缓存的配置如下: <cache name="org.hibernate.cache.UpdateTimestampsCache" maxElementsInMemory="5000" eternal="true" overflowToDisk="true"/> <cache name="org.hibernate.cache.StandardQueryCache" maxElementsInMemory="10000" eternal="false" timeToLiveSeconds="120" overflowToDisk="true"/> 3、 选择缓存策略依据: <cache usage="transactional|read-write|nonstrict-read-write|read-only" (1)/> ehcache不支持transactional,其他三种可以支持。 read-only:无需修改, 那么就可以对其进行只读 缓存,注意,在此策略下,如果直接修改数据库,即使能够看到前台显示效果, 但是将对象修改至cache中会报error,cache不会发生作用。另:删除记录会报错,因为不能在read-only模式的对象从cache中删除。 read-write:需要更新数据,那么使用读/写缓存 比较合适,前提:数据库不可以为serializable transaction isolation level (序列化事务隔离级别) nonstrict-read-write:只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离, 那么比较适合使用非严格读/写缓存策略。 4、 调试时候使用log4j的log4j.logger.org.hibernate.cache=debug,更方便看到ehcache的操作过程,主要用于调试过程,实际应用发布时候,请注释掉,以免影响性能。 5、 使用ehcache,打印sql语句是正常的,因为query cache设置为true将会创建两个缓存区域:一个用于保存查询结果集 ( org.hibernate.cache.StandardQueryCache);另一个则用于保存最近查询的一系列表的时间戳(org.hibernate.cache.UpdateTimestampsCache)。 请注意:在查询缓存中,它并不缓存结果集中所包含的实体的确切状态;它只缓存这些实体的标识符属性的值、以及各值类型的结果。 需要将打印sql语句与最近的cache内容相比较,将不同之处修改到cache中,所以查询缓存通常会和二级缓存一起使用。 Ehcache的配置说明 <ehcache> <!-- 磁盘存储配置: 用来指定缓存在磁盘上的存储位置。可以使用JavaVM环境变量(user.home, user.dir, java.io.tmpdir) \--> <diskStore path = "/var/apps/cache/" /> <!-- 指定CacheManagerEventListenerFactory,这个对象在缓存添加的时候会得到相应的通知 CacheManagerEventListenerFactory的属性 \*class - CacheManagerEventListenerFactory的一个实现类 \*properties - CacheManagerEventListenerFactory的属性值,以逗号(,)分割多个属性 如果没有实现类被指定,则系统不创建CacheManager的监听器,没有默认值 \--> <cacheManagerEventListenerFactory class="" properties="" /> <!-- 在进行分布式缓存的应用时候需要指定CacheManagerPeerProviderFactory, 用来生成CacheManagerPeerProvider的实例,以便和集群中的其他CacheManager通信。 \*class -CacheManagerPeerProviderFactory的一个实现类 \*properties - CacheManagerPeerProviderFactory的属性值,以逗号(,)分割多个属性 Ehcache内建了2种基于RMI分布系统的通信策略: \*automatic - 使用多播组。在一个节点加入或者推出集群的时候自动感应 \*manual - 硬编码方式 目前的awf中不考虑分布缓存 \--> <cacheManagerPeerListenerFactory class="" properties="" /> <!-- 缓存配置。 以下属性是必须的: name - cache的标识符,在一个CacheManager中必须唯一 maxElementsInMemory - 在内存中缓存的element的最大数目 maxElementsOnDisk - 在磁盘上缓存的element的最大数目 eternal - 设定缓存的elements是否有有效期。如果为true,timeouts属性被忽略 overflowToDisk - 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上 以下属性是可选的: timeToIdleSeconds - 缓存element在过期前的空闲时间。默认为0,表示可空闲无限时间. (如果指定了这个时间,是否在被hit的前超过了这个时间就会被remove?在内存缓存数目超限之前不会被remove) timeToLiveSeconds - 缓存element的有效生命期。这个类似于timeouts,默认为0,不过期 (是否通常情况下应该大于等于timeToIdleSeconds,小于会如何?idle时间也会减小和这个数值一样) diskPersistent - 在VM重启的时候是否持久化磁盘缓存,默认是false。 (测试一下true的情况?重载vm的时候会从磁盘进行序列化到对象) diskExpiryThreadIntervalSeconds - 磁盘缓存的清理线程运行间隔,默认是120秒. (测试一下0的时候会如何) memoryStoreEvictionPolicy - 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。默认是LRU,可选的有LFU和FIFO 可对缓存中的element配置诸如监听器和加载器。Ehcahe内建了一些 \*cacheEventListenerFactory - 监听缓存中element的put, remove, update和expire事件 \*bootstrapCacheLoaderFactory - 启动时加载缓存的element 每个用来做分布式缓存都必须设定element的事件监听器,用来在各个CacheManager节点复制消息。 Ehcache内建了基于RMI的实现 - RMICacheReplicatorFactory <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory" properties="replicateAsynchronouly=true, replicatePuts=true, replicateUpdates=true, replicateUpdateViaCopy=true, replicateRemovals=true" /> \--> <cache .... /> <!-- 默认的Cache配置。用来实现CacheManager.add(String cacheName)创建的缓存 \--> <defaultCache maxElementsInMemory="10000" eternal="false" timeToIdleSeconds="120" timeToLiveSeconds="120" overflowToDisk="true" maxElementsOnDisk="1000000" diskPersistent="false" diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU" /> </ehcache> [None.gif]: /images/20220731/6b0cddfae5884578ae2a3f61db998ce8.png
还没有评论,来说两句吧...