MyBatis笔记——MyBatis缓存
什么是MyBatis缓存
当 mybatis 执行sql时,会创建缓存,下次执行相同语句时,会直接使用缓存的结果
优点
- 减少重复sql的计算时间
MyBatis 一级缓存
一级缓存是SqlSession级别的
SqlSession sqlSession = SqlSessionUtils.getSqlSession();
CacheMapper cacheMapper = sqlSession.getMapper(CacheMapper.class);
@Test
public void testGetEmpByEid() {
log.info("emp:{}",cacheMapper.GetEmpByEid(4));
CacheMapper cacheMapper1 = sqlSession.getMapper(CacheMapper.class);
log.info("emp1:{}",cacheMapper1.GetEmpByEid(4));
}
一级缓存失效的四种情况
- 不同的SqlSession对应不同的一级缓存
- 同一个SqlSession但是查询条件不同
- 同一个SqlSession两次查询期间执行了任何一次增删改查
- 同一个SqlSession手动清除了缓存
MyBatis 二级缓存
二级缓存是 SqlSessionFactory 级别的
开启二级缓存需要满足一下条件:
- 在核心配置文件中,设置全局配置属性cacheEnabled="true",默认为true,不需要设置
- 在映射文件中设置标签<cache>标签
- 二级缓存必须在SqlSession关闭或提交后生效
- 查询的数据所转换的实体类型必须实现序列化接口
@Test
public void testTwoCache() throws IOException {
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
SqlSession sqlSession = sqlSessionFactory.openSession(true);
log.info("emp1:{}",sqlSession.getMapper(CacheMapper.class).GetEmpByEid(4));
sqlSession.close();
SqlSession sqlSession1 = sqlSessionFactory.openSession(true);
log.info("emp2:{}",sqlSession1.getMapper(CacheMapper.class).GetEmpByEid(4));
}
<cache>
标签
属性 | 作用 | 参数选项 |
---|---|---|
eviction | 缓存回收策略 | LRU (Least Recently Used)-最近最少使用的:移除最长时间不被使用的对象。FIFO (First in First out)-先进先出:按对象进入缓存的顺序来移除它们。SOFT -软引用:移除基于垃圾回收器状态和软引用规则的对象。WEAK -弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象。默认的是 LRU 。 |
flushInterval | 刷新间隔,单位毫秒 | 默认不设置,就是缓存仅调用语句时刷新 |
size | 引用数目,正整数 | 缓存可以存储多少个对象 |
readOnly | 只读 | true: 只读缓存,会给所有调用者返回缓存对象的相同实例。因此这些对象不能被修改。这提供了很重要的性能优势。 false: 读写缓存,会返回缓存对象的拷贝(通过序列化)。这会慢一些,但是安全,因此默认是flse。 |
二级缓存失效情况
两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效
MyBatis 缓存数据的顺序
- 先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。
- 如果二级缓存没有命中,再查询一级缓存
- 如果一级缓存也没有命中,则查询数据库
- SqlSession关闭之后,一级缓存中的数据会写入二级缓存
- 感谢你赐予我前进的力量
赞赏者名单
因为你们的支持让我意识到写文章的价值🙏
本文是原创文章,采用 CC BY-NC-ND 4.0 协议,完整转载请注明来自 zxb
评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果