提高检索效率的利器--Mybatis 的一级缓存和二级缓存执行顺序

😀前言
本篇博文是关于MyBatis缓存的执行顺序,希望能够帮助到您😊

🏠个人主页:晨犀主页
🧑个人简介:大家好,我是晨犀,希望我的文章可以帮助到大家,您的满意是我的动力😉😉

💕欢迎大家:这里是CSDN,我总结知识的地方,欢迎来到我的博客,感谢大家的观看🥰
如果文章有什么需要改进的地方还请大佬不吝赐教 先在次感谢啦😊

Mybatis 的一级缓存和二级缓存执行顺序

缓存-官方文档

文档地址: https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#cache

Mybatis 的一级缓存和二级缓存执行顺序

缓存执行顺序是:二级缓存–>一级缓存–>数据库
说的再多不如眼见为实,让我们用代码来证明吧

测试

代码实现
  1. 修改com\nlc\mapper\MonsterMapperTest.java
    演示二级缓存->一级缓存->DB执行的顺序
    @Test
    public void cacheSeqTest() {

        System.out.println("查询第1次");
        //DB, 会发出SQL, 分析cache hit ratio 0.0
        Monster monster1 = monsterMapper.getMonsterById(3);
        System.out.println(monster1);

        //这里关闭sqlSession, 一级缓存数据没有
        //当我们关闭一级缓存的时候,如果你配置二级缓存,那么一级缓存的数据,会放入到二级缓存
        sqlSession.close();

        sqlSession = MyBatisUtils.getSqlSession();
        monsterMapper = sqlSession.getMapper(MonsterMapper.class);

        System.out.println("查询第2次");
        //从二级缓存获取id=3 monster , 就不会发出SQL, 分析cache hit ratio 0.5
        Monster monster2 = monsterMapper.getMonsterById(3);
        System.out.println(monster2);

        System.out.println("查询第3次");
        //从二级缓存获取id=3 monster, 不会发出SQL, 分析cache hit ratio 0.6666
        Monster monster3 = monsterMapper.getMonsterById(3);
        System.out.println(monster3);

        if (sqlSession != null) {
            sqlSession.close();
        }
        System.out.println("操作成功");

    }
运行结果
查询第1Cache Hit Ratio [com.nlc.mapper.MonsterMapper]: 0.0
Opening JDBC Connection
Created connection 527829831.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1f760b47]
==>  Preparing: SELECT * FROM `monster` WHERE id = ?
==> Parameters: 3(Integer)
<==    Columns: id, age, birthday, email, gender, name, salary
<==        Row: 3, 51, 4015-09-12, qwrw@df.com, 1, 风衣精, 1965
<==      Total: 1
Monster{id=3, age=51, name='风衣精', email='qwrw@df.com', birthday=Sat Sep 12 00:00:00 CST 4015, salary=1965.0, gender=1}
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1f760b47]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1f760b47]
Returned connection 527829831 to pool.
查询第2Cache Hit Ratio [com.nlc.mapper.MonsterMapper]: 0.5
Monster{id=3, age=51, name='风衣精', email='qwrw@df.com', birthday=Sat Sep 12 00:00:00 CST 4015, salary=1965.0, gender=1}
查询第3Cache Hit Ratio [com.nlc.mapper.MonsterMapper]: 0.6666666666666666
Monster{id=3, age=51, name='风衣精', email='qwrw@df.com', birthday=Sat Sep 12 00:00:00 CST 4015, salary=1965.0, gender=1}
操作成功

细节说明

  1. 不会出现一级缓存和二级缓存中有同一个数据。因为二级缓存(数据)是在一级缓存关闭之后才有的。
  2. 看这段代码, 修改com\nlc\mapper\MonsterMapperTest.java , 不关闭一级缓存, 看看运行效果
 //分析缓存执行顺序
    //二级缓存->一级缓存->DB
    //因为二级缓存(数据)是在一级缓存关闭之后才有的
    @Test
    public void cacheSeqTest2() {

        System.out.println("查询第1次");

        //DB , 会发出 SQL, cache hit ratio 0.0
        Monster monster1 = monsterMapper.getMonsterById(3);
        System.out.println(monster1);

        //这里我们没有关闭sqlSession

        System.out.println("查询第2次");
        //从一级缓存获取id=3 , cache hit ratio 0.0, 不会发出SQL
        Monster monster2 = monsterMapper.getMonsterById(3);
        System.out.println(monster2);

        System.out.println("查询第3次");
        //还是从一级缓存获取id=3, cache hit ratio 0.0, 不会发出SQL
        Monster monster3 = monsterMapper.getMonsterById(3);
        System.out.println(monster3);

        if (sqlSession != null) {
            sqlSession.commit();
            sqlSession.close();
        }
        System.out.println("操作成功");

    }
  1. 运行效果, 可以看到,在一级缓存存在的情况下,依然是先查询二级缓存,但是因为二级缓存,没有数据, 所以命中率都是0.0 , 可以debug 下。
查询第1Cache Hit Ratio [com.nlc.mapper.MonsterMapper]: 0.0
Opening JDBC Connection
Created connection 485845532.
Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1cf56a1c]
==>  Preparing: SELECT * FROM `monster` WHERE id = ?
==> Parameters: 3(Integer)
<==    Columns: id, age, birthday, email, gender, name, salary
<==        Row: 3, 51, 4015-09-12, qwrw@df.com, 1, 风衣精, 1965
<==      Total: 1
Monster{id=3, age=51, name='风衣精', email='qwrw@df.com', birthday=Sat Sep 12 00:00:00 CST 4015, salary=1965.0, gender=1}
查询第2Cache Hit Ratio [com.nlc.mapper.MonsterMapper]: 0.0
Monster{id=3, age=51, name='风衣精', email='qwrw@df.com', birthday=Sat Sep 12 00:00:00 CST 4015, salary=1965.0, gender=1}
查询第3Cache Hit Ratio [com.nlc.mapper.MonsterMapper]: 0.0
Monster{id=3, age=51, name='风衣精', email='qwrw@df.com', birthday=Sat Sep 12 00:00:00 CST 4015, salary=1965.0, gender=1}
Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@1cf56a1c]
Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@1cf56a1c]
Returned connection 485845532 to pool.
操作成功

😄总结

  1. 缓存执行顺序是:二级缓存–>一级缓存–>数据库
  2. 二级缓存(数据)是在一级缓存关闭之后才有的。
  3. 二级缓存和一级缓存都是为了提高检索效率的技术,最大的区别就是作用域的范围不一样。
  4. 一级缓存的作用域是sqlSession 会话级别,在一次会话有效,而二级缓存作用域是全局范围,针对不同的会话都有效。

😁热门专栏推荐
对缓存感兴趣的朋友可以看看博主的缓存篇–
MyBatis缓存-提高检索效率的利器–一级缓存
MyBatis缓存-提高检索效率的利器–二级缓存

文章到这里就结束了,如果有什么疑问的地方请指出,诸大佬们一起来评论区一起讨论😁
希望能和诸大佬们一起努力,今后我们一起观看感谢您的阅读🍻
如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

晨犀

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值