Hibernate的二级缓存
二级缓存是属于SessionFactory级别的缓存机制。第一级别的缓存是Session级别的缓存,是属于事务范围的缓存,由Hibernate管理,一般无需进行干预。第二级别的缓存是SessionFactory级别的缓存,是属于进程范围的缓存。可以被所有的Session共享。
分类
二级缓存也分为了两种
内置缓存:Hibernate自带的,不可卸载,通常在Hibernate的初始化阶段,Hibernate会把映射元数据和预定义的SQL语句放置到SessionFactory的缓存中。该内置缓存是只读的。
外置缓存:通常说的二级缓存也就是外置缓存,在默认情况下SessionFactory不会启用这个缓存插件,外置缓存中的数据是数据库数据的复制,外置缓存的物理介质可以是内存或者硬盘。
访问策略
与并发访问数据库一致,二级缓存也提供了四种访问策略,分别对应四种类似的隔离级别。我们一般采用read-write(读写即读已提交)
transactional (事务型) | 仅在受管理的环境中适用 提供Repeatable Read事务隔离级别 适用经常被读,很少修改的数据 可以防止脏读和不可重复读的并发问题 缓存支持事务,发生异常的时候,缓存也能够回滚 |
read-write (读写型) | 提供Read Committed事务隔离级别 在非集群的环境中适用 适用经常被读,很少修改的数据 可以防止脏读 更新缓存的时候会锁定缓存中的数据 |
nonstrict-read-write (非严格读写型) | 适用极少被修改,偶尔允许脏读的数据(两个事务同时修改数据的情况很少见) 不保证缓存和数据库中数据的一致性 为缓存数据设置很短的过期时间,从而尽量避免脏读 不锁定缓存中的数据 |
read-only (只读型) | 适用从来不会被修改的数据(如参考数据) 在此模式下,如果对数据进行更新操作,会有异常 事务隔离级别低,并发性能高 在集群环境中也能完美运作 |
适合放入二级缓存中数据
很少被修改
不是很重要的数据,允许出现偶尔的并发问题
不适合放入二级缓存中的数据
经常被修改
财务数据,绝对不允许出现并发问题
与其他应用数据共享的数据
二级缓存是可配置的插件
二级缓存的实现:
1.添加jar包
hibernate-release-4.3.11.Final\lib\optional\ehcache\*.jar
2.添加配置文件
拷贝Desktop\hibernate-release-4.3.11.Final\project\etc\ehcache.xml到src下
3.开启二级缓存
<propertyname="cache.use_second_level_cache">true</property>
4.配置使用的二级缓存的产品
<propertyname="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
5.配置对哪些类使用hibernate的二级缓存(二选一)
5.1在cfg中配置(统一配置)
<class-cacheusage="read-write"class="base.many2oneBoth.Emp"/>
5.2在类对应的hbm中配置
- <class name="Dept" table="customers" >
- <!-- 类级别缓存 -->
- <cache usage="read-write"/>
- <idname="customerid"type="int">
- <columnname="CUSTOMER_ID"/>
- </id>
- </class>
- </span>
6.配置对集合使用二级缓存
对dept使用二级缓存
<mappingresource="base/many2oneBoth/dept.hbm.xml"/>
对集合使用二级缓存(属性全路径)缓存集合包含对象的所有id
也可以在对应的hbm的set中添加子元素配置
<collection-cacheusage="read-write"
collection="base.many2oneBoth.Dept.emps"/>
配置对集合中每个元素使用二级缓存
<mappingresource="base/many2oneBoth/emp.hbm.xml"/>
配置文件详解:
<ehcache>
<!-- 设置当缓存对象益出时,对象保存到磁盘时的保存路径。
如 d:\xxxx
The following properties are translated:
user.home - User's home directory
user.dir - User's current working directory
java.io.tmpdir - windows的临时目录 -->
<diskStore path="java.io.tmpdir"/>
<!--默认数据过期策略
maxInMemory - 缓存中可以存入的最多个对象数
eternal - true:表示永不失效,false:不是永久有效的。
timeToIdleSeconds - 空闲时间,当第一次访问后在空闲时间内没有访问,则对象失效,单位为秒
timeToLiveSeconds - 被缓存的对象有效的生命时间,单位为秒
overflowToDisk 当缓存中对象数超过核定数(益出时)时,对象是否保存到磁盘上。true:保存;false:不保存
如果保存,则保存路径在标签<diskStore>中属性path指定
-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
<!-- 设定具体的命名缓存数据过期策略
对于类而言name="base.many2oneBoth.Emp"
对于集合而言name="base.many2oneBoth.Dept.orders"
-->
<cache name="base.many2oneBoth.Emp"
maxElementsInMemory="1"
eternal="false"
timeToIdleSeconds="1000"
timeToLiveSeconds="2000"
overflowToDisk="true"
/>
</ehcache>