简述
作用域(org.apache.ibatis.session.LocalCacheScope)
- SESSION
- STATEMENT
生命周期
一级缓存也称为会话缓存,生命周期同sqlsession一致,开始到结束基本就是几秒
缓存容器
HashMap,即内存.不选用ConcurrentHashMap因为sqlsession也不是线程安全的.
命中流程
- 执行器父类 BaseExecutor调用query()方法
- 检测是否存在一级缓存,如果存在知己去一级缓存中取出并返回
- 如果不存在则调用doQuery()方法查询数据库,填充到一级缓存中并返回
命中条件
1. 缓存命中即当前查询条件组成的key在缓存的map中存在才能命中,下图是缓存的key组成
- updateList[0]:当前查询的statement,即必须是同一个查询,相同的statementID
- updateList[1]/ updateList[2]:分页数据,即RowBounds要相同
- updateList[3]/ updateList[4]:相同的sql语句,参数
- updateList[5]:环境相同,即配置的环境参数
2.未清空缓存才能命中,清空缓存的操作有:
- 在mapper.xml或者注解形式的sql中配置了flushCache=true
- 提交,回滚,执行update(所有不是select的都是update)
- 缓存作用域是statement,在seting中设置localCacheScope
mybatis整合spring,mybatis一级缓存失效
执行结果false
简单分析:因为每一次都开启一个新的session
红框这里不能保存session,所以每次都会打开一个新的session;加上事务后一级缓存就可以生效了,详细讲解可以看鲁班大叔的mybatis视频
总结(美团技术团队总结[聊聊MyBatis缓存机制 - 美团技术团队])
- MyBatis一级缓存的生命周期和SqlSession一致。
- MyBatis一级缓存内部设计简单,只是一个没有容量限定的HashMap,在缓存的功能性上有所欠缺。
- MyBatis的一级缓存最大范围是SqlSession内部,有多个SqlSession或者分布式的环境下,数据库写操作会引起脏数据,建议设定缓存级别为Statement。
记录学习[鲁班大叔]视频