Mybatis框架
缓存
在Mybatis里面,所谓的缓存就是将已经查询过的记录放在内存的缓冲区或文件上,这样如果再次查询,可以通过配置的策略,命中已经查询过的记录.从而提高查询的效率.
缓存作用
提高查询的效率.
一级缓存
Mybatis的缓存分为一级缓存\ 二级缓存
一级缓存:所谓的一级缓存就是会话(SqlSesion对象)级别的缓存,就是同一个会话,如果已经查询过的数据会保存一份在内存中,如果会话没有关闭,再次调用同样的方法查询,不会再查询数据库,而是直接从缓存中取出之前查询的数据.
一级缓存默认是打开的,而且是关闭不了的.
如何清空一级缓存.
1.关闭会话.close()
2.进行了操作(增删改),提交了commit();
3.手工清除缓存clearCache()
测试代码
@Test
public void testselectAll() {
// 1.创建SqlSession对象
//SqlSesion对象默认就开启了一级缓存,将已经查询过的数据就缓存到SqlSession的缓存区域
//在此会话中如果再次发送同样的请求,那么直接从缓存区域获取数据,不会再发送SQL语句了
SqlSession session1 = MyBatisUtil.openSession();
//SqlSession session2 = MyBatisUtil.openSession();
// 2.创建UserMapper接口的代理对象
UserMapper mapper1 = session1.getMapper(UserMapper.class);
//UserMapper mapper2 = session2.getMapper(UserMapper.class);
//3.执行查询方法
List<User> users1 = mapper1.selectAll();
//手动清理缓存
session1.clearCache();
List<User> users2 = mapper1.selectAll();
}
二级缓存
一级缓存是SqlSession对象级别,在每一次会话中有效
二级缓存是 SqlSessionFactory级别,在整个应用都有效,可以在多个会话有效
MyBatis本身并没有实现二级缓存
二级缓存需要第三方缓存提供商的支持
Ehcache -第三方缓存(Hibernate框架默认就是支持)
学习地址
http://www.mybatis.org/ehcache-cache/
下载ehcache
https://github.com/mybatis/ehcache-cache/releases
配置开启二级缓存
MyBatis开启二级缓存新版本已经默认支持开启二级缓存.可以不改
<settings>
<!-- 开启二级缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>
导入Ehcachejar包
Ehcache依赖 slfj 日志框架,必须要导入slfj的两个jar包
创建 ehcache.xml配置文件
Ehcache有自己的配置文件,在src下面创建ehcache.xml 配置文件
<ehcache>
<!-- 缓存的磁盘位置 -->
<diskStore path="D:/mybatis_cache"/>
<!-- 默认的缓存策略: 如果开发者在某一个需要缓存的文件配置了自定义缓存,就不使用默认的,如果没有配置,就使用默认缓存策略-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
</ehcache>
在映射文件中配置以及配置对应的缓存策略
<mapper namespace="cn.zj.mybatis.dao.UserMapper">
<!-- 当前表的映射开启支持二级缓存,并设置相关的缓存提供商,以及缓存的相关配置 -->
<cache type="org.mybatis.caches.ehcache.EhcacheCache" >
<!--最大的空闲时间 -->
<property name="timeToIdleSeconds" value="10000"/>
<!-- 最大的在线时间 -->
<property name="timeToLiveSeconds" value="20000"/>
<!-- 内存的大小 b字节 m1 =1024k 1k=1024b -->
<property name="maxEntriesLocalHeap" value="2000000"/>
<!-- 文件的大小 b字节-->
<property name="maxEntriesLocalDisk" value="20000000"/>
<!-- 算法 LRU:最少使用优先, "LFU" or "FIFO:先进先出 -->
<property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>
<select id="selectAll" resultType="User">
select * from user
</select>
</mapper>
因为二级缓存可以缓存到文件(将对象序列化到本地),涉及到对象序列化,那么对应的javaBean对象就必须实现
public class User implements Serializable{
private static final long serialVersionUID = -8366151150155170110L;
}
缓存的命中率
命中率= 从缓存中获取数据的次数/ 查询的总次数
如 : 两次查询 从缓中获取一次
0.5 = 1/2;
0.666666 = 2/3;
命中率越高缓存效果越好
DEBUG [main] - Cache Hit Ratio [cn.zj.mybatis.mapper.UserMapper]: 0.0
DEBUG [main] - ==> Preparing: select * from user where id = ?
DEBUG [main] - ==> Parameters: 3(Integer)
DEBUG [main] - <== Total: 1
DEBUG [main] - Cache Hit Ratio [cn.zj.mybatis.mapper.UserMapper]: 0.5
DEBUG [main] - Cache Hit Ratio [cn.zj.mybatis.mapper.UserMapper]: 0.6666666666666666
DEBUG [main] - Cache Hit Ratio [cn.zj.mybatis.mapper.UserMapper]: 0.75
DEBUG [main] - Cache Hit Ratio [cn.zj.mybatis.mapper.UserMapper]: 0.8
DEBUG [main] - Cache Hit Ratio [cn.zj.mybatis.mapper.UserMapper]: 0.8333333333333334
DEBUG [main] - Cache Hit Ratio [cn.zj.mybatis.mapper.UserMapper]: 0.8571428571428571
DEBUG [main] - Cache Hit Ratio [cn.zj.mybatis.mapper.UserMapper]: 0.875
DEBUG [main] - Cache Hit Ratio [cn.zj.mybatis.mapper.UserMapper]: 0.8888888888888888
DEBUG [main] - Cache Hit Ratio [cn.zj.mybatis.mapper.UserMapper]: 0.9