查询缓存
一级缓存:同一个SqlSession对象
MyBatis默认开启一级缓存,如果用同样的SqlSession对象查询相同的数据,则只会在第一次查询时向数据库发送SQL语句,并将查询结果放入SqlSession中,后续再次查询该同样的对象时,则直接从缓存中查询该对象即可(即省略了数据库的访问)
二级缓存
1.mybatis自带二级缓存:同一个namespace生成的mapper对象
mybatis默认情况没有开启二级缓存,需要手工打开。
a、config.xml配置
<settings>
<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
b、在具体的xxxMapper.xml中声明开启
<!-- namespace:该mapper.xml映射文件的唯一标识 -->
<mapper namespace="org.lanqiao.mapper.PersonMapper">
<!-- 声明此namespace开启二级缓存 -->
<cache/>
</mapper>
Mybatis的二级缓存是将对象放入硬盘文件中
序列化(Serializable):内存 --> 硬盘
反序列化(UnSerializable):硬盘 --> 内存
c、准备缓存的对象,必须实现了序列化接口(该对象、对象的级联属性和对象的父类都需要实现序列化接口),例如:
public class Person implements Serializable
触发将对象写入二级缓存的时机:SqlSession对象的close()方法
namespace的值就是接口的全类名(包名.类名),通过接口可以产生代理对象(xxxMapper对象)
结论:只要产生的xxxMapper对象来自同一个namespace,则这些对象共享二级缓存。
注意:二级缓存的范围是同一个namespace,如果有多个xxxMapper.xml的namespace值相同,则通过这些xxxMapper.xml产生的xxxMapper对象仍然共享二级缓存。
2.禁用二级缓存
select标签中useCache=“false”
<!-- 关闭此select的二级缓存useCache="false" -->
<select id="queryClassAndPersons" parameterType="int" resultMap="Class_Person" useCache="false">
select c.*,p.* from person p join personClass c on p.classId=c.classId where p.classId=#{classId}
</select>
3.清理二级缓存:
a、与清理一级缓存的方法相同
commit();(一般执行增删改时会清理掉缓存,设计的原因是为了防止脏数据)
在二级缓存中,commit()不能是查询自身的commit。
b、在select标签中增加属性flushCache="true"
三方提供的二级缓存
ehcache、memcache
要想整合三方提供的二级缓存(或者自定义二级缓存),必须实现org.apache.ibatis.cache.Cache接口,该接口的默认实现类是PerpetualCache
整合ehcache二级缓存:
a、导入jar包
Ehcache-core.jar
mybatis-Ehcache.jar
slf4j-api.jar
b、编写ehcache配置文件 Ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
<!-- 当二级缓存的对象超过内存限制时(缓存对象的个数>maxElementsInMemory),存放入的硬盘文件 -->
<diskStore path="D:\Ehcache"/>
<!--
maxElementsInMemory:设置在内存中缓存对象的个数
maxElementsOnDisk:设置在硬盘中缓存对象的个数
eternal:设置缓存是否永远不过期
overflowToDisk:当内存中缓存的对象个数超过maxElementsInMemory时,是否转移到硬盘中
timeToIdleSeconds:当两次访问的时间间隔超过该值时,则缓存对象失效
timeToLiveSeconds:一个缓存对象最多存放的时间(生命周期)
diskExpiryThreadIntervalSeconds:设置每隔多长时间来通过一个线程清理硬盘中的缓存
memoryStoreEvictionPolicy:当超过缓存对象的最大值时,处理的策略:LRU、FIFO、IFU
-->
<defaultCache
maxElementsInMemory="1000"
maxElementsOnDisk="1000000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="100"
timeToLiveSeconds="100"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
c、开启Ehcache二级缓存
//在xxxMapper.xml中开启
<!-- 三方的二级缓存 -->
<cache type="org.mybatis.caches.ehcache.EhcacheCache">
<!-- 修改Ehcache.xml中的默认属性值 -->
<!-- <property name="maxElementsInMemory" value="2000"/> -->
</cache>