MyBatis笔记五
一、查询缓存(只在查询,增删改没有):
一级缓存
同一个SqlSession对象
默认开启一级缓存,如果用同样的SqlSession对象查询相同的数据,则只会在第一次查询时向数据库发送SQL语句,并将结果返回到Sqlsession对象中,后续再次查询同样对象时就可从缓存中直接查询该对象
二级缓存
(一)、Mybatis自带二级缓存
同一个namespace生成的mapper对象
(namespace即为 接口的全类名(包名.类名)可以通过通过接口产生代理对象)
默认关闭二级缓存
二级缓存在硬盘中,某个文件(所以需要close)
结论:只要产生的xxMapper对象来自于同一个namespace, 则这些对象共享二级缓存。
如果是多个Mapper.xml的namespace相同,那么他们也共享二级缓存
- 先在conf.xml中的开启二级缓存
< setting name="cacheEnabled" value="true"/ >
- 在mapper.xml中申明开启二级缓存
<cache/>
- 对象及级联属性和父类 序列化
public class Person implements Serializable {
}
- 触发二级缓存时机:session.close();
因为是写入硬盘中,不可能每个文件都提交一次,所以一般是每次close的时候提交二级缓存
(二) 、 三方提供的二级缓存
ehcache
要想整合三方提供的二级缓存(或者自定 义二级缓存),必须实现org. apache. ibatis. cache.Cache接口
1. 整合ehcache二级缓存需要的jar包:
Ehcache-core. jar
mybatis-Ehcache. jar
slf4j-api. jar
2.编写ehcache配置文件
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
updateCheck="false" dynamicConfig="false">
<diskStore path="F:\J\Ehcacahe"/>
<!--
maxElementsInMemory : 设置在 内存 中的缓存对象个数
maxElementsOnDisk : 设置在 硬盘 中的缓存对象个数
eternal : 设置缓存是否永不过期
overflowToDisk : 当内存中缓存超过maxElementsInMemory后是否转移到硬盘中
timeToIdleSeconds : 两次访问间隔时间,超过则缓存对象失效
timeToLiveSeconds : 一个缓存对象最多存放时间(生命周期)
diskExpiryThreadIntervalSeconds : 设置每隔多少时间通过一个线程来清理硬盘中的缓存
memoryStoreEvictionPolicy : 当超过缓存对象最大值时,处理策略
-->
<defaultCache
maxElementsInMemory= "1000"
maxElementsOnDisk= "1000000"
eternal="false"
overflowToDisk= "false "
timeToIdleSeconds= "100"
timeToLiveSeconds="100"
diskExpiryThreadIntervalSeconds= "120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
缓存的3种清空策略 :
FIFO ,first in first out (先进先出).
LFU , Less Frequently Used (最少使用).意思是一直以来最少被使用的。缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存。
LRU ,Least Recently Used(最近最少使用). (ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存
3.开启第三方二级缓存
<!-- 第三方二级缓存 -->
<cache type="org.mybatis.caches.ehcache.EhcacheCache">
<!-- 可不配置,配置了则覆盖 -->
<property name="maxElementsInMemory" value="2000"/>
</cache>
二、二级缓存的禁用:
单个sql语句可禁用二级缓存,
在select中修改useCache="false"
二、缓存的清理:
1. commit
无论是一级还是二级,清理缓存只需要 commit();
但二级缓存中不能是查询自身的commit();
原因:为了防止脏数据,如果修改数据后缓存中的值不变就和查询的结果不同了
2. 标签
在select中修改flushCache="true"