一级缓存的命中场景
运行时参数相关
- 同一个会话 : 同一个sqlSession对象调用
- sql语句相同, 参数相同
- 相同的statementID : 选中的蓝色框
- 相同的分页参数
操作与配置相关
- 未手动清空缓存
- 未配置flushCache = true
- 未执行update操作
- 缓存作用域不是STATEMENT
一级缓存查询流程
mybatis结合spring导致一级缓存失效
失效的主要原因就是 : 在不开启事务的情况下, 通过mapper每次查询都会重新生成一个sqlSession对象, 不满足同一个会话
实例
可以看出, 两次查询出来的对象不相同, 因此没有走一级缓存
源码分析
spring 与 mybatis结合每次查询执行的流程如下 :
分析
进入45行
首先就进入MapperProxy的代理类中, 执行invoke()方法
进入85行的invoke()方法
最后进入MapperMethod类的execute()方法
进入到87行
此时已经进入到SqlSessionTemplate类中, 同时160行的sqlSessionProxy对象还是代理对象, 进入160行之后, 会进入到sqlSessionProxy对象实现的InvocationHandler的invoke方法中
424行获取对应sqlSession对象, 让我们看一下如何获取, 进入424行
97行的holder对象是ThreadLocal类型的, 如果在同一个事务中99行获得的session不会是null, 会重用同一个事务中的sqlsession对象, 如果为空则通过105行重新创建一个sqlsession对象
之后427行通过反射执行方法, 获取数据库中的数据
== 现在可以看出, 在不同事务下, 每次查询都会重新生成一个sqlsession对象 ==