MyBatis(二)缓存,springboot多模块项目架构

本文深入探讨MyBatis的一级和二级缓存机制,包括命中条件、源码解析、结构及失效情况。一级缓存为会话级,二级缓存为应用级,能跨线程使用,具有较高的命中率。同时,文章讨论了SpringBoot集成MyBatis时一级缓存失效的问题及解决方案。
摘要由CSDN通过智能技术生成

缓存


MyBatis共有两级缓存

  • 一级缓存:在Base Executor实现

  • 二级缓存:在Caching Executor实现

一级缓存命中条件

一级缓存不能打开,存储结构为Key-Value形式,底层为一个HashMap,当一级缓存命中时,Sql只会被编译处理一次

作用:当执行完一句查SQL的时候,再调用时,产生的两个对象是一致的,而且SQL只被编译和使用一次,因为第二次调用的时候,取得对象是从一级缓存中取得

命中相关条件

  • 运行时参数相关

  • 操作与配置相关

命中条件

  1. Sql和参数相同

  2. statementID要一样

  3. 方法名不一样,接口名不一样,也就是方法的全限定名称不一样都会导致StatementID不一样

  4. 不同的会话,执行相同的Sql的StateMentID会不一样(一级缓存被称为Session缓存)

  5. 使用不同的RowBounds进行分页,也会导致StatementID不一样

  6. 查询后清空缓存也不会命中缓存

  7. 方法加上注解flushCache=true

  8. 调用session的clearCache方法

  9. 当主动去调用mapper进行增删改操作的时候(这个增删改的判定是根据注解和配置形式来决定的,而不是sql决定,比如@Delete(select * …)也会被视作删除操作从而清空缓存),也会自动清空一次缓存(否则会产生数据一致性问题)

  10. 关闭一级缓存,修改localCacheScope改成STATEMENT(但此时不是真正关闭,嵌套查询依然会走缓存)

  11. 子查询不会清空缓存,因为子查询是要依赖一级缓存的

所以总的来说

运行时参数

  • sql和参数相同

  • 相同的statementID,即方法的全限定名称一样

  • sqlSession一样(会话级缓存)

  • RowBounds分页也一样

操作与配置

  • 不清空缓存(提交、回滚操作都会清空缓存,还有手动清空)

  • 不配置flushCache=true

  • 不执行update语句,即不执行增删改语句

  • 启用一级缓存,也就是缓存的作用域不改为STATEMENT

一级缓存源码解析

首先认识MyBatis执行SQl的一套流程

  1. 动态代理Mapper

  2. 创建SqlSession

  3. SqlSession中调用Executor

  4. Executor调用StatementHandler去处理SQL

  5. 在数据库执行SQL

而一级缓存(LocalCache)的调用,就在Executor中,具体来说是在BaseExecutor中,(BaseExecutor执行query方法时,会先查看是否存在一级缓存,不存在会执行doQuery方法(这个方法的具体实现是在调用的BaseExecutor实例中,将SQL放入数据库里面执行后,然后填充缓存),存在则使用PerpeturalCache,一级缓存的实现是在PerpetualCache中的,不需要继续走数据库执行SQL

一级缓存结构

一级缓存具体的结构其实是一个HashMap

  • Key:由SQL、Ses

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值