使用缓存, 我们可以避免频繁的与数据库进行交互
MyBatis 内置了一个强大的事务性查询缓存机制,它可以非常方便地配置和定制, 分为一级缓存和二级缓存。 但是在默认的情况下, 只开启一级缓存(一级缓存是对同一个 SqlSession 而言的)
一级缓存
一级缓存也叫本地缓存:sqlSession
- 与数据库同一次会话期间查询到的数据会存放在本地缓存中
- 如果需要获取相同的数据,直接从缓存中拿,无需再去查询数据库
测试步骤:
1.开启日志
2.测试在一个sqlSession中查询两次相同的记录
@Test
public void test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.queryUserById(1);
System.out.println(user);
System.out.println("=======================");
User user1 = mapper.queryUserById(1);
System.out.println(user1);
System.out.println("=======================");
System.out.println(user==user1);
sqlSession.close();
3. 查看日志输出
缓存失效的情况:
- 增删改操作,可能会改变原来的数据,所以必定会刷新缓存
- 查询不同的信息
- 查询不同的Mapper
- 手动清理缓存
二级缓存
二级缓存也叫全局缓存,一级缓存作用域太低了,所以诞生了二级缓存
基于namespace级别的缓存,一个命名空间,对应一个二级缓存
工作机制:
- 一个会话查询一条数据,这个数据就会被放在当前会话的以及缓存中
- 如果当前会话关闭了,这个会话对应的一级缓存就没了;但是我们想要的是,会话关闭了,一级缓存中的数据被保存到二级缓存中
- 新的会话查询信息就可以从二级缓存中获取内容
- 不同的mapper查询的数据会放在自己对应的缓存(map)中
测试步骤:
1. 显示的开启全局缓存(尽管默认是开启的)
<settings> <setting name="cacheEnabled" value="true"/> </settings>
2.在使用二级缓存的Mapper中开启
<!-- 在当前Mapper.xml中使用二级缓存--> <cache/>
也可以自定义参数
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
3.测试
我们需要将实体类序列化,否则会报错
小结:
只要开启了二级缓存,在同一Mapper下就有效
所有的数据都会先放在一级缓存中
只有当会话提交,或者关闭的时候,才会提交到二级缓存中