Mybatis一级缓存案例演示 & 源码级原理探究~~~

2021/12/20 9:19:59

本文主要是介绍Mybatis一级缓存案例演示 & 源码级原理探究~~~,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

文章目录

    • 简介
    • 什么是Mybatis一级缓存?
    • 案例演示
      • 基于同一个SqlSession实验
      • 基于不同SqlSession实验
    • 小结论
    • 源码探究
    • 回顾标题:Mybatis一级缓存是什么???
    • 最后总结
    • 为什么一级缓存又叫查询缓存?
    • Java入门到就业学习路线规划
    • 小白快速入门Python爬虫路线

简介

作者: Code皮皮虾

作者简介:华为云享专家、掘金创作者、CSDN Java领域优质创作者、HDZ 核心组成员、JavaCodes公众号运营者!

有兴趣的,可以关注一下公众号,有问题的话可以进行交流!


什么是Mybatis一级缓存?

Mybatis中的一级缓存又叫查询缓存,顾名思义:只有查询才能缓存,更新、删除、插入等等不会会使用到。

这个一级缓存就是说:在执行一次SQL查询或者SQL更新之后,这条SQL语句并不会消失,而是被MyBatis 缓存起来,当再次执行相同SQL语句的时候,就会直接从缓存中进行提取,而不是再次执行SQL命令从数据库中查询。


案例演示


基于同一个SqlSession实验

如下是根据用户ID查询用户,我们分别查询三次

@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日志只打印了一次

image-20211111100757434

既然如此,那我们在第一次和第二次之间清空一下缓存,那么会打印出几条日志呢???

@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);

}

相信聪明的小伙伴已经想到了会打印出两条日志

image-20211111101047450

当然,以上是基于同一个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的查询是独立的

image-20211111101440825


小结论

一级缓存(查询缓存)是 SqlSession级别 的缓存。不同的 sqlSession 之间的缓存区域(HashMap)是互相不影响的。

image-20211111102124701


源码探究

image-20211111103211410

image-20211111103327628

继续下一步

image-20211111103345761

来到关键方法,可以看到下面是通过 switch 判断类型,我们是查询,所以可以直接来到 SELECT case中

image-20211111103409745

可以看到SELECT 的case中有一行关键的代码,就是通过SqlSession调用的 selectOne方法,我们直接进去

image-20211111103514057

**selectOne中会调用当前类的 selectList方法,我们继续进去 **

image-20211111103620228

继续进去

image-20211111103756067

来到关键的 query方法 ,可以看到这里会去创建 缓存Key

image-20211111103818152

第一次进来,cache为null,所以直接调用return的方法

image-20211111104005680

关键!关键!关键!关键!关键!关键!关键!

image-20211111104250510

image-20211111104547729


回顾标题:Mybatis一级缓存是什么???

看了下面这张图相信大家都懂了,一级缓存(查询缓存)就是一个HashMap,而且每个SqlSession中有着各自独立的HashMap,跟ThreadLocal有点异曲同工之妙。

image-20211111104740717


最后总结

Mybatis一级缓存是SqlSession级别的缓存,对于SqlSession内部有着HashMap进行缓存,各个SqlSession之间互不干扰,通过构造唯一key,确保多次执行相同SQL时,可以在之后的执行中直接从缓存中获取,减小数据库访问压力。

构造唯一key

image-20211111105853668


为什么一级缓存又叫查询缓存?

因为最后在BaseExecutor中进行执行的时候都没有像查询一样去缓存获取数据,也没有将数据缓存的操作

insert、delete、update在BaseExecutor中调用的都是update方法,所以都没有涉及到缓存。

image-20211111110040752



Java入门到就业学习路线规划

关注底部公众号回复: Java学习路线,即可领取全套资料

在这里插入图片描述


小白快速入门Python爬虫路线

关注底部公众号回复: 爬虫学习路线,即可领取全套资料

在这里插入图片描述



这篇关于Mybatis一级缓存案例演示 & 源码级原理探究~~~的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!


扫一扫关注最新编程教程