1、一级缓存
缓存可以将数据保存在内存中,是互联网系统常常用到的。目前流行的缓存服务器有 MongoDB、Redis、Ehcache 等。缓存是在计算机内存上保存的数据,读取时无需再从磁盘读入,因此具备快速读取和使用的特点.
一级缓存是基于 PerpetualCache(MyBatis自带)的 HashMap 本地缓存,作用范围为 session 域内。当 session flush(刷新)或者 close(关闭)之后,该 session 中所有的 cache(缓存)就会被清空。默认情况下Mybatis只开启一级缓存。
缓存只针对查询功能有效
一级缓存失效的四种情况:
- 不同的SqlSession对应不同的一级缓存
- 同一个SqlSession但查询条件不同
- 同一个SqlSession两次查询期间执行了任何一次增删改操作
- 同一个SqlSession两次查询期间手动清空了缓存
public class CacheTest {
@Test
public void testCache(){
/*SqlSession sqlSession1 = SqlSessionUtils.getSqlSession();
CacheMapper mapper1 = sqlSession1.getMapper(CacheMapper.class);
Emp emp1 = mapper1.getEmpByEid(1);
System.out.println(emp1);*/
SqlSession sqlSession2 = SqlSessionUtils.getSqlSession();
CacheMapper mapper2 = sqlSession2.getMapper(CacheMapper.class);
Emp emp2 = mapper2.getEmpByEid(1);
System.out.println(emp2);
//clearCache()方法会清空一级缓存
sqlSession2.clearCache();
Emp emp3 = mapper2.getEmpByEid(1);
System.out.println(emp3);
}
}
在使用增删改操作时,会自动进行一级缓存清空,也可以使用clearCache()方法手动清空一级缓存
2、二级缓存
二级缓存是全局缓存,作用域超出 session 范围之外,可以被所有 SqlSession 共享。一级缓存缓存的是 SQL 语句,二级缓存缓存的是结果对象
二级缓存的开启:
1)MyBatis 的全局缓存配置需要在 mybatis-config.xml 的 settings 元素中设置置属性cacheEnabled=“true”(默认为true可以不设置):
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
2)在映射文件(CatchMapper.xml)中设置cache标签
cache标签中的属性,该标签用于设置缓存回收策略
3)二级缓存必须在SqlSession关闭或提交之后才有效
4)查询的数据所转换的实体类类型必须实现序列化的接口(对象序列化的作用和意义)
将Emp实体类实现序列化接口:
当两次查询之间执行了任意的增删改,会使一级缓存和二级缓存都失效。
3、MyBatis缓存查询的顺序
- 先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。
- 如果二级缓存没有命中,再查询一级缓存
- 如果一级缓存也没有命中,则查询数据库
- SqlSession关闭之后,一级缓存中的数据会写入二级缓存