Mybatis缓存的生命周期、使用的特殊情况

以下场景均在Spring Boot程序中,并非手动创建SqlSession使用。

在回答这个问题之前,我们先来回顾一下,Mybatis的一级二级缓存是啥。

一级二级缓存

是什么

  1. 一级缓存(本地缓存):一级缓存是SqlSession级别的缓存,当我们执行查询时,MyBatis会先将查询结果放在当前SqlSession的缓存中,如果后续有相同的查询,MyBatis会直接从缓存中取出结果,而不会再次执行 SQL 查询。
  2. 二级缓存(全局缓存):二级缓存是 Mapper 级别的缓存,它可以被多个SqlSession共享。当一个SqlSession 查询数据时,MyBatis会先在一级缓存中查找,如果没有找到,再去二级缓存中查找,如果还没有找到,最后才会去数据库查询。
缓存类型 生命周期 如何开启 位置
一级缓存 随SqlSession的生命周期 默认启用,无法关闭 BaseExecutorlocalCache参数中
二级缓存 跟随程序的生命周期 xml文件标识<cache/>或者使用@CacheNamespace注解 MappedStatement中的cache参数

问题

回到问题本身,其实就是一个缓存生命周期的回答,是否每次都会使用呢?

并不是,得看是如何使用的。有两种情况:

  1. 显式使用SqlSession:在查询后,没有显式调用clearCache并且在同一个上下文二次查询后,缓存使用。
java 复制代码
try (SqlSession session = sqlSessionFactory.openSession()) {
    // 第一次查询,将结果放入缓存
    session.select();
    
    // 第二次查询,直接使用上一次的搜索结果
    session.select();
    // 清除缓存
    session.clearCache();
}
  1. 由Spring容器管理的SqlSession:在Spring中,每次调用Mapper的方法都会创建一个新的SqlSession,自然而然也不会使用缓存了。当然,开启了事务另说。

题外话

有没有什么额外回答能在回答的时候加一下分呢?

那么我们就要想想在什么场景下,使用了上一次的搜索结果会有问题呢?

没错就是它:数据库的事务隔离级别

在MySQL中不同的事务隔离级别 对查询起着不同的影响

其中在可重复读(REPEATABLE READ)以下的级别都会受到Mybatis 一级二级缓存的影响。那么为什么呢?

读未提交(READ UNCOMMITTED)、读已提交(READ COMMITTED)都可以在事务查询时获取到其他事务的结果,所以如果使用了Mybatis的缓存 的话,就跟数据库的查询结果不一致了。

相关推荐
2501_941800887 小时前
Java高性能搜索引擎与Lucene实战分享:大规模文本索引、检索与优化经验
mybatis
大猫子的技术日记7 小时前
[百题重刷]前缀和 + Hash 表:缓存思想, 消除重复计算
java·缓存·哈希算法
愤怒的山羊8 小时前
jetcache List 缓存, json 序列化 泛型解析成了 JsonObject 处理
缓存·json·list
树在风中摇曳8 小时前
带哨兵位的双向循环链表详解(含 C 代码)+ LeetCode138 深度解析 + 顺序表 vs 链表缓存机制对比(图解 CPU 层级)
c语言·链表·缓存
q***428210 小时前
SpringCloud-持久层框架MyBatis Plus的使用与原理详解
spring·spring cloud·mybatis
北郭guo11 小时前
MyBatis框架讲解,工作原理、核心内容、如何实现【从浅入深】让你看完这篇文档对于MyBatis的理解更加深入
java·数据库·mybatis
斯文~12 小时前
「玩透ESA」站点配置阿里云ESA全站加速+自定义规则缓存
阿里云·缓存·云计算·cdn·esa
S***t71412 小时前
Python装饰器实现缓存
缓存
天硕国产存储技术站13 小时前
3000次零失误验证,天硕工业级SSD筑牢国产SSD安全存储方案
缓存·固态硬盘·国产ssd
前端炒粉16 小时前
35.LRU 缓存
开发语言·javascript·数据结构·算法·缓存·js