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

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,高可用系列 2核4GB
云数据库 RDS PostgreSQL,高可用系列 2核4GB
简介: 提高检索效率的利器--Mybatis 的一级缓存和二级缓存执行顺序

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("操作成功");
    }


运行结果

查询第1次
Cache 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.
查询第2次
Cache 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}
查询第3次
Cache 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 下。
查询第1次
Cache 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}
查询第2次
Cache 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}
查询第3次
Cache 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 会话级别,在一次会话有效,而二级缓存作用域是全局范围,针对不同的会话都有效。


文章到这里就结束了,如果有什么疑问的地方请指出,诸大佬们一起来评论区一起讨论😁

希望能和诸大佬们一起努力,今后我们一起观看感谢您的阅读🍻

如果帮助到您不妨3连支持一下,创造不易您们的支持是我的动力🤞

相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
MySQL数据库入门学习
本课程通过最流行的开源数据库MySQL带你了解数据库的世界。 &nbsp; 相关的阿里云产品:云数据库RDS MySQL 版 阿里云关系型数据库RDS(Relational Database Service)是一种稳定可靠、可弹性伸缩的在线数据库服务,提供容灾、备份、恢复、迁移等方面的全套解决方案,彻底解决数据库运维的烦恼。 了解产品详情:&nbsp;https://www.aliyun.com/product/rds/mysql&nbsp;
相关文章
|
存储 缓存 芯片
让星星⭐月亮告诉你,当我们在说CPU一级缓存二级缓存三级缓存的时候,我们到底在说什么?
本文介绍了CPU缓存的基本概念和作用,以及不同级别的缓存(L1、L2、L3)的特点和工作原理。CPU缓存是CPU内部的存储器,用于存储RAM中的数据和指令副本,以提高数据访问速度,减少CPU与RAM之间的速度差异。L1缓存位于处理器内部,速度最快;L2缓存容量更大,但速度稍慢;L3缓存容量最大,由所有CPU内核共享。文章还对比了DRAM和SRAM两种内存类型,解释了它们在计算机系统中的应用。
1340 1
|
4月前
|
存储 缓存 NoSQL
mybatisplus一二级缓存
MyBatis-Plus 继承并优化了 MyBatis 的一级与二级缓存机制。一级缓存默认开启,作用于 SqlSession,适用于单次会话内的重复查询;二级缓存需手动开启,跨 SqlSession 共享,适合提升多用户并发性能。支持集成 Redis 等外部存储,增强缓存能力。
|
6月前
|
缓存 Java 数据库连接
Mybatis一级缓存详解
Mybatis一级缓存为开发者提供跨数据库操作的一致性保证,有效减轻数据库负担,提高系统性能。在使用过程中,需要结合实际业务场景选择性地启用一级缓存,以充分发挥其优势。同时,开发者需注意其局限性,并做好事务和并发控制,以确保系统的稳定性和数据的一致性。
211 20
|
缓存 Java 数据库连接
mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存及第三方缓存)
文章介绍了MyBatis的缓存机制,包括一级缓存和二级缓存的配置和使用,以及如何整合第三方缓存EHCache。详细解释了一级缓存的生命周期、二级缓存的开启条件和配置属性,以及如何通过ehcache.xml配置文件和logback.xml日志配置文件来实现EHCache的整合。
mybatis复习05,mybatis的缓存机制(一级缓存和二级缓存及第三方缓存)
|
8月前
|
缓存 Java 数据库连接
Mybatis一级缓存、二级缓存详讲
本文介绍了MyBatis中的查询缓存机制,包括一级缓存和二级缓存。一级缓存基于同一个SqlSession对象,重复查询相同数据时可直接从缓存中获取,减少数据库访问。执行`commit`操作会清空SqlSession缓存。二级缓存作用于同一namespace下的Mapper对象,支持数据共享,需手动开启并实现序列化接口。二级缓存通过将数据存储到硬盘文件中实现持久化,为优化性能,通常在关闭Session时批量写入缓存。文章还说明了缓存的使用场景及注意事项。
292 7
Mybatis一级缓存、二级缓存详讲
|
9月前
|
缓存 Java 数据库连接
十、MyBatis的缓存
十、MyBatis的缓存
180 6
|
10月前
|
缓存 NoSQL Java
Mybatis学习:Mybatis缓存配置
MyBatis缓存配置包括一级缓存(事务级)、二级缓存(应用级)和三级缓存(如Redis,跨JVM)。一级缓存自动启用,二级缓存需在`mybatis-config.xml`中开启并配置映射文件或注解。集成Redis缓存时,需添加依赖、配置Redis参数并在映射文件中指定缓存类型。适用于查询为主的场景,减少增删改操作,适合单表操作且表间关联较少的业务。
197 6
|
SQL 缓存 Java
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
本文详细介绍了MyBatis的各种常见用法MyBatis多级缓存、逆向工程、分页插件 包括获取参数值和结果的各种情况、自定义映射resultMap、动态SQL
【详细实用のMyBatis教程】获取参数值和结果的各种情况、自定义映射、动态SQL、多级缓存、逆向工程、分页插件
|
11月前
|
缓存 Java 数据库连接
深入探讨:Spring与MyBatis中的连接池与缓存机制
Spring 与 MyBatis 提供了强大的连接池和缓存机制,通过合理配置和使用这些机制,可以显著提升应用的性能和可扩展性。连接池通过复用数据库连接减少了连接创建和销毁的开销,而 MyBatis 的一级缓存和二级缓存则通过缓存查询结果减少了数据库访问次数。在实际应用中,结合具体的业务需求和系统架构,优化连接池和缓存的配置,是提升系统性能的重要手段。
439 4
|
11月前
|
缓存 Java 数据库连接
MyBatis缓存机制
MyBatis提供两级缓存机制:一级缓存(Local Cache)默认开启,作用范围为SqlSession,重复查询时直接从缓存读取;二级缓存(Second Level Cache)需手动开启,作用于Mapper级别,支持跨SqlSession共享数据,减少数据库访问,提升性能。
197 1