文章目录
简介
作者: Code皮皮虾
作者简介:华为云享专家、掘金创作者、CSDN Java领域优质创作者、HDZ 核心组成员、JavaCodes公众号运营者!
有兴趣的,可以关注一下公众号,有问题的话可以进行交流!
什么是Mybatis一级缓存?
Mybatis中的一级缓存又叫查询缓存,顾名思义:只有查询才能缓存,更新、删除、插入等等不会会使用到。
这个一级缓存就是说:在执行一次SQL查询或者sql更新之后,这条sql语句并不会消失,而是被MyBatis 缓存起来,当再次执行相同sql语句的时候,就会直接从缓存中进行提取,而不是再次执行sql命令从数据库中查询。
案例演示
基于同一个sqlSession实验
@Test
void getUserById() {
//获取sqlSession
sqlSession sqlSession = MybatisUtils.gersqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = userDao.getUserById(1);
System.out.println(user);
System.out.println("==================");
UserDao userDao1 = sqlSession.getMapper(UserDao.class);
User user1 = userDao1.getUserById(1);
System.out.println(user1);
System.out.println("==================");
UserDao userDao2 = sqlSession.getMapper(UserDao.class);
User user2 = userDao2.getUserById(1);
System.out.println(user2);
}
查看执行结果,可以看到只有执行第一次查询的时候才是从数据库中查询的,第二次、三次都是直接从缓存中拿去的数据
所以Mybatis日志只打印了一次
既然如此,那我们在第一次和第二次之间清空一下缓存,那么会打印出几条日志呢???
@Test
void getUserById() {
sqlSession sqlSession = MybatisUtils.gersqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = userDao.getUserById(1);
System.out.println(user);
System.out.println("==================");
//清空缓存
sqlSession.clearCache();
UserDao userDao1 = sqlSession.getMapper(UserDao.class);
User user1 = userDao1.getUserById(1);
System.out.println(user1);
System.out.println("==================");
UserDao userDao2 = sqlSession.getMapper(UserDao.class);
User user2 = userDao2.getUserById(1);
System.out.println(user2);
}
相信聪明的小伙伴已经想到了会打印出两条日志
当然,以上是基于同一个sqlSession的情况下来进行实验的,那么接下来我们基于不同sqlSession实验
基于不同sqlSession实验
@Test
void getUserById() {
sqlSession sqlSession1 = MybatisUtils.gersqlSession();
UserDao userDao = sqlSession1.getMapper(UserDao.class);
User user = userDao.getUserById(1);
System.out.println(user);
System.out.println("==================");
sqlSession sqlSession2 = MybatisUtils.gersqlSession();
UserDao userDao1 = sqlSession2.getMapper(UserDao.class);
User user1 = userDao1.getUserById(1);
System.out.println(user1);
System.out.println("==================");
sqlSession sqlSession3 = MybatisUtils.gersqlSession();
UserDao userDao2 = sqlSession3.getMapper(UserDao.class);
User user2 = userDao2.getUserById(1);
System.out.println(user2);
}
小结论
一级缓存(查询缓存)是 sqlSession级别 的缓存。不同的 sqlSession 之间的缓存区域(HashMap)是互相不影响的。
源码探究
继续下一步
来到关键方法,可以看到下面是通过 switch 判断类型,我们是查询,所以可以直接来到 SELECT case中
可以看到SELECT 的case中有一行关键的代码,就是通过sqlSession调用的 selectOne方法,我们直接进去
**selectOne中会调用当前类的 selectList
方法,我们继续进去 **
继续进去
来到关键的 query
方法 ,可以看到这里会去创建 缓存Key
第一次进来,cache为null,所以直接调用return的方法
关键!关键!关键!关键!关键!关键!关键!
回顾标题:Mybatis一级缓存是什么???
看了下面这张图相信大家都懂了,一级缓存(查询缓存)就是一个HashMap,而且每个sqlSession中有着各自独立的HashMap,跟ThreadLocal有点异曲同工之妙。
最后总结
Mybatis一级缓存是sqlSession级别的缓存,对于sqlSession内部有着HashMap进行缓存,各个sqlSession之间互不干扰,通过构造唯一key,确保多次执行相同sql时,可以在之后的执行中直接从缓存中获取,减小数据库访问压力。
构造唯一key
为什么一级缓存又叫查询缓存?
因为最后在BaseExecutor中进行执行的时候都没有像查询一样去缓存获取数据,也没有将数据缓存的操作
Java入门到就业学习路线规划
小白快速入门Python爬虫路线
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。