1、Hibernate二级缓存
Hibernate包括两个级别的缓存:
1、一级缓存:默认总是启用的session级别的。
2、二级缓存:可选的SessionFactory级别的。
Session级别的以及缓存总是有效的,当应用保持持久化实体、修改持久化实体时,Session并不会吧这种改变flush到数据库,而是缓存在当前Session的一级缓存中,除非程序显示调用session的flush方法,或者查询关闭session时,才会把这先改变一次性的flush到底层数据库,这样可以减少与数据库的交互,从而提高数据库的访问性能。
SessionFactory级别的二级缓存是全局的,应用的所有的Seeion都共享这个二级缓存,当Session需要抓取数据时,Session就会优先从二级缓存中抓取。(主要包括实体缓存,查询缓存)。
2、适用范围
主要适合以下数据放入二级缓存:
1. 很少被修改,大量查询的
2. 不是很重要的数据,允许出现偶尔并发访问的
3、Hibernate二级缓存的配置
1. 需要以下架包:
2.我们需要在Hibernate的配置文件中设置二级缓存的相关信息
一般Hibernate的二级缓存实体和属性的缓存映射,如果需要将查询数据也二级缓存,需要使用hibernate.cache.use_query_cache开启。
4、Ehcache的配置
ehcache.xml的配置文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="true"
monitoring="autodetect"
dynamicConfig="true" >
<!--这里的路径是在你发布的服务器下temp中-->
例如:
<diskStore path="java.io.tmpdir/ehcache_hsrj" />
<!--
name:Cache的唯一标识
maxElementsInMemory:内存中最大缓存对象数
maxElementsOnDisk:磁盘中最大缓存对象数,若是0表示无穷大
eternal:Element是否永久有效,一但设置了,timeout将不起作用
overflowToDisk:配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中
timeToIdleSeconds:设置Element在失效前的允许闲置时间。仅当element不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大
timeToLiveSeconds:设置Element在失效前允许存活时间。最大时间介于创建时间和失效时间之间。仅当element不是永久有效时使用,默认是0.,也就是element存活时间无穷大
diskPersistent:是否缓存虚拟机重启期数据
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)
-->
<defaultCache maxElementsInMemory="10000" eternal="false"
timeToIdleSeconds="1200"
timeToLiveSeconds="3600"
overflowToDisk="true"
maxElementsOnDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU" />
<!-- hibernate 缓存机制
timeToIdleSeconds=120;
timeToLiveSeconds=180;
(表示此缓存最多可以存活3分钟,如果期间超过2分钟未访问 那么此缓存失效!) -->
<cache name="org.hibernate.cache.StandardQueryCache"
maxElementsInMemory="5000" eternal="false" timeToLiveSeconds="3600"
timeToIdleSeconds="1800"
overflowToDisk="false" />
<cache name="org.hibernate.cache.UpdateTimestampsCache"
maxElementsInMemory="5000" eternal="true" overflowToDisk="true" />
<!-- 针对某个实体类特殊处理时添加缓存的方式 -->
<!--
<cache
name="com.hsrj.system.entity.Suser"
maxElementsInMemory="2"
memoryStoreEvictionPolicy="LRU"
eternal="true"
diskPersistent="false"
overflowToDisk="false"
maxElementsOnDisk="1000000" />
-->
<!-- springMVC cache缓存机制
Url: http://blog.csdn.net/sdmxdzb/article/details/44241353
使用springMVC+ ehcache 缓存 -->
</ehcache>
第一段是配置默认的ehcache二级缓存信息,第二段是特殊的配置(需要配置特殊时)。
4.1、配置详解
name:缓存名称。
maxElementsInMemory:缓存最大个数。
eternal:对象是否永久有效,一但设置了,timeout将不起作用。
timeToIdleSeconds:设置对象在失效前的允许闲置时间(单位:秒)。仅当eternal=false对象不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置对象在失效前允许存活时间(单位:秒)。最大时间介于创建时间和失效时间之间。仅当eternal=false对象不是永久有效时使用,默认是0.,也就是对象存活时间无穷大。
overflowToDisk:当内存中对象数量达到maxElementsInMemory时,Ehcache将会对象写到磁盘中。
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
maxElementsOnDisk:硬盘最大缓存个数。
diskPersistent:是否缓存虚拟机重启期数据 Whether the disk store persists between restarts of the Virtual Machine. The default value is false.
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。
clearOnFlush:内存数量最大时是否清除。
5、配置需二级缓存实体和属性
这里只介绍注解形式的,xml形式的不说了,大多数公司都用注解。
在实体类和实体的那些集合属性上启用二级缓存使用
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
注:如果一个实体需要二级缓存,若该实体含有<set...>,<list...>等属性时,也必须要指定缓存策略。
例如:
5.1、缓存usage事务隔离机制
Usage提供缓存对象的事务隔离机制有如下几种:
(NONE, READ_ONLY, NONSTRICT_READ_WRITE, READ_WRITE, TRANSACTIONAL)
ehcache不支持transaction事务机制,但其他三种可以使用:
read-only::
无需修改, 那么就可以对其进行只读 缓存,注意,在此策略下,如果直接修改数据库,即使能够看到前台显示效果,
但是将对象修改至cache中会报error,cache不会发生作用。另:删除记录会报错,因为不能在read-only模式的对象从cache中删除。
read-write:
需要更新数据,那么使用读/写缓存 比较合适,前提:数据库不可以为serializable transaction isolation level(序列化事务隔离级别)
nonstrice-read-write:
只偶尔需要更新数据(也就是说,两个事务同时更新同一记录的情况很不常见),也不需要十分严格的事务隔离,那么比较适合使用非严格读/写缓存策略。
6、使用查询缓存
查询缓存所缓存的key值就是查询所使用的HQL或SQL语句,需要注意的是:查询缓存不仅要求所使用的HQL语句、SQL语句相同,甚至是要求所传入的参数也相同,Hibernate才能从缓存中查去数据。
查询缓存有如下两步:
1、查询缓存不不仅开启 hibernate.cache.use_query_cache
2、还需要在查询时使用 setCacheable(true)