MyBatis(二)缓存

命中相关条件

  • 运行时参数相关

  • 操作与配置相关

命中条件

  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、Session、分页条件、参数等一系列东西组成的

  • Value:就是缓存的查出来的结果

[](()一级缓存总结

  1. 与会话相关

  2. 参数条件相关

  3. 提交、修改会清空缓存

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值