MyBatis 的多级缓存机制是怎么样运作的?

news2024/11/24 23:10:17

引言:上周三,小 X 去面试一家中厂,其中面试官问到 MyBatis 的多级缓存机制是怎么样运行的?这个问题可以好好准备一下,很多人可能只会用 MyBatisPlus,简单的多表联查 SQL 语句可能都写不出来,更别说索引优化、SQL 语句优化、安全漏洞等问题了,先打好基础,才能更好地学习。

题目

MyBatis 的多级缓存机制是怎么样运作的?

推荐解析

一级缓存

1)MyBatis 的一级缓存默认开启,且默认作用范围为 SESSION,即一级缓存在一个会话中生效,也可以通过配置将作用范围设置为 STATEMENT,让一级缓存仅针对当前执行的 SQL 语句生效。
2)在同一个会话中,执行增,删,改操作会使本会话中的一级缓存失效。
3)不同会话持有不同的一级缓存,本会话内的操作不会影响其它会话内的一级缓存。

Session 针对浏览器会话,不同会话的同一个 SQL 语句,自然是不会走一级缓存。同一个浏览器会话,但是查询条件不同,比如 Where 条件不同,依然不会走一级缓存,或者同一个浏览器在两个相同的查询条件下,中间执行了一次增、删、改的操作,一级缓存依然失效。

**特别注意:**一级缓存针对的范围是什么?以及一级缓存失效的场景,当然一般我们都会在 yml 配置中去开启日志,通过查看日志可以看到缓存是否被使用!

二级缓存

1) MyBatis 中的二级缓存默认开启,可以在 MyBatis 配置文件中的<settings>中添加<setting name="cacheEnabled" value="false"/>将二级缓存关闭;
2)MyBatis 中的二级缓存作用范围是同一命名空间下的多个会话共享,这里的命名空间就是映射文件的 namespace,即不同会话使用同一映射文件中的 SQL 语句对数据库执行操作并提交事务后,均会影响这个映射文件持有的二级缓存;
3)MyBatis 中执行查询操作后,需要提交事务才能将查询结果缓存到二级缓存中;
4)MyBatis 中执行增,删或改操作并提交事务后,会清空对应的二级缓存;
5)MyBatis 中需要在映射文件中添加<cache>标签来为映射文件配置二级缓存,也可以在映射文件中添加<cache-ref>标签来引用其它映射文件的二级缓存以达到多个映射文件持有同一份二级缓存的效果。

二级缓存配置项

在 Mapper 配置文件中添加的 Cache 标签中可以设置相关属性。

1)Eviction 属性:缓存回收策略(LRU、FIFO、SOFT、WEAK)

2)FlushInterval属性:刷新间隔,单位毫秒,默认没有刷新间隔,语句被调用时缓存会刷新。

3)Size:引用的数目,缓存存储的对象数量,考虑到内存溢出问题。

4)ReadOnly:只读,是否是只读缓存,如果为 true,所有调用者返回缓存对象的相同实例。如果为 false,会返回缓存对象的拷贝(序列化对象),性能慢,但安全性高,默认为 false。

是否需要三级缓存?

概念:三级缓存通常指的是在分布式系统中,跨应用实例的缓存层,如使用 Redis 或 Memcached 作为缓存存储。

作用:三级缓存可以进一步减少对数据库的访问,提高系统的扩展性和性能。

考虑因素:是否需要三级缓存取决于应用的规模、架构和性能需求。如果应用部署在多个服务器上,且需要共享数据,可能需要考虑引入三级缓存。

实现:三级缓存通常不是由 MyBatis 直接提供,而是通过集成外部缓存系统来实现。

应用规模:对于大型应用或分布式系统,三级缓存可以提供更好的性能和扩展性。

性能需求:如果应用对性能有较高要求,尤其是在高并发场景下,三级缓存可以显著减少数据库的压力。

数据一致性:引入三级缓存需要考虑数据一致性问题,确保缓存与数据库之间的数据同步。

复杂性:实现三级缓存可能会增加系统的复杂性,需要权衡实现成本和性能收益。

其他补充

鱼聪明 AI 的回答:

鱼聪明 AI 地址:https://www.yucongming.com/

一级缓存示例:

一级缓存是自动启用的,不需要额外配置。它通常在 SqlSession 的生命周期内有效。

// 获取 SqlSession
SqlSession session = sqlSessionFactory.openSession();

try {
    // 查询用户,一级缓存会自动存储这个查询结果
    User user1 = session.selectOne("com.example.mapper.User.selectById", 1L);

    // 再次查询相同的用户,这次将从一级缓存中获取结果
    User user2 = session.selectOne("com.example.mapper.User.selectById", 1L);

    // 检验缓存是否失效:在一级缓存中,可以通过比较 user1 和 user2 是否相同来检验
    if (user1 == user2) {
        System.out.println("一级缓存有效");
    } else {
        System.out.println("一级缓存失效");
    }

} finally {
    session.close(); // 关闭 SqlSession,结束一级缓存的生命周期
}

二级缓存示例:

二级缓存需要在 MyBatis 配置文件中配置,并在 Mapper 接口上使用 @CacheNamespace 注解。

<!-- mybatis-config.xml -->
<configuration>
    <settings>
        <!-- 启用二级缓存 -->
        <setting name="cacheEnabled" value="true"/>
    </settings>
    
    <!-- 配置二级缓存的类型,这里使用 MyBatis 内置的 PerpetualCache -->
    <cache type="org.apache.ibatis.cache.impl.PerpetualCache">
        <!-- 二级缓存的大小限制 -->
        <property name="size" value="1024"/>
    </cache>
</configuration>
// 在 Mapper 接口上使用 @CacheNamespace 注解
@CacheNamespace
public interface UserMapper {
    User selectById(Long id);
}
// 使用二级缓存的示例
SqlSession session = sqlSessionFactory.openSession();

try {
    // 查询用户,结果将被存储在二级缓存中
    User user1 = session.getMapper(UserMapper.class).selectById(1L);

    // 关闭当前会话,然后重新打开一个新的会话
    session.close();
    session = sqlSessionFactory.openSession();

    // 在新的会话中再次查询相同的用户,这次将从二级缓存中获取结果
    User user2 = session.getMapper(UserMapper.class).selectById(1L);

    // 检验缓存是否失效:在二级缓存中,可以通过比较 user1 和 user2 是否相同来检验
    if (user1 == user2) {
        System.out.println("二级缓存有效");
    } else {
        System.out.println("二级缓存失效");
    }

} finally {
    session.close(); // 关闭 SqlSession
}

检验缓存是否失效:

  • 一级缓存:由于一级缓存仅在 SqlSession 的生命周期内有效,通常不需要手动检验缓存是否失效。当 SqlSession 关闭时,一级缓存自动失效。
  • 二级缓存:可以通过比较两次查询返回的对象引用是否相同来检验缓存是否失效。如果相同,说明缓存有效;如果不同,说明缓存可能已经失效。

欢迎交流

本文主要介绍 MyBatis 的一二级缓存和缓存失效的主要场景,以及是否需要三级缓存的问题,关于数据库方面是一个重点项,因为不同语言都需要利用数据库进行持久化存储,无论哪种 ORM 框架都有各自的优缺点,需要根据实际场景进行选择,在文末还有三个提问,欢迎小伙伴在评论区进行留言!近期面试鸭小程序已全面上线,想要刷题的小伙伴可以积极参与!

1)一级缓存和二级缓存的区别是什么?

2)如何配置和管理二级缓存?

3)MyBatis的一级缓存是如何工作的?它的生命周期是什么时候开始和结束的?什么情况下会导致一级缓存的失效或刷新?

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1828727.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

MySql 各种 join

MySql 定义了很多join的方式&#xff0c;接下来我们用一个例子来讲解。 用到的表 本文用到了两个表s1,s2&#xff1a; 内外连接 测试 1 1 1.select * from s1 inner join s2 on(s1.id s2.id);&#xff1a; -------- | id | id | -------- | 3 | 3 | | 4 | 4 | --------2…

sqlite3模块的使用

1. SQLite数据库 SQLite是一个轻量级的, 基于磁盘的, 关系型的数据库管理系统(RDBMS). 它不需要一个独立的服务器进程或操作系统级别的配置. SQLite是D.Richard Hipp在2000年创建的, 并且由于其小巧, 快速, 可靠和易于使用的特性, 它在全球范围内得到了广泛的应用.以下是 SQLi…

最长回文子串问题详解

最长回文子串的问题描述&#xff1a;给出一个字符串S&#xff0c;求S的最长回文子串的长度。 针对这个问题&#xff0c;先看暴力解法&#xff1a;枚举子串的两个端点i和j&#xff0c;判断在[i,j]区间内的子串是否回文。从复杂度上来看&#xff0c;枚举端点需要&#xff0c;判断…

【招联消费金融股份】有限公司2024年5月18日【算法开发岗暑期实习】一面试经验分享

招联消费金融股份有限公司2024年5月18日面试经验分享 面试流程&#xff1a;共30多分钟&#xff0c;先3分钟自我介绍&#xff0c;然后细细介绍简历上面的论文和实习信息。问题1&#xff1a;扩散模型的noise schedule有什么研究。问题2&#xff1a;有哪些常见的数学分布问题3&…

数据结构:冒泡排序,选择排序,插入排序,希尔排序的实现分析

✨✨小新课堂开课了&#xff0c;欢迎欢迎~✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;数据结构与算法 小新的主页&#xff1a;编程版小新-CSDN博客 1.冒泡排序 1.1算法思想 冒泡排序的基本思想就是&a…

关于Java

关于Java Java语言关于并发JVM调优工具写在最后 Java语言 Java语言作为当下主流开发语言&#xff0c;其面向对象的开发模式以及一次编译多次运行&#xff0c;跨平台运行以及自动的垃圾回收机制可以说是给开发者节省了很大的时间用于逻辑功能的开发&#xff0c;那么在开发过程中…

【靶场搭建】-02- 搭建OWASP靶机

1.OWASP靶机介绍 相比较其他靶机&#xff0c;OWASP提供的环境更多&#xff0c;且包含了许多其他靶机的环境&#xff0c;属于性价比比较高的靶机了。 2.下载OWASP 访问以下地址进行下载&#xff1a; https://sourceforge.net/projects/owaspbwa/ 因为OWASP是虚拟机文件&…

C++初学者指南第一步---1. C++开发环境设置

C初学者指南第一步—1. C开发环境设置 目录 C初学者指南第一步---1. C开发环境设置1.1 工具1.1.1 代码编辑器和IDE1.1.2 Windows1.1.3 命令行界面 1.2 编译器1.2.1 gcc/g (支持Linux/Windows/MacOSX)1.2.2 clang/clang (支持Linux/Windows/MacOS)1.2.3 Microsoft Visual Studio…

Jackson的使用

一引入依赖 <!--Jackson是spring-boot-starter-json的一个依赖&#xff08;spring-boot-starter-web中包含spring-boot-starter-json&#xff09;。也就是说&#xff0c;当项目中引入spring-boot-starter-web后会自动引入spring-boot-starter-json --> <dependency&g…

vue关于:deep穿透样式的理解

情况一 子组件&#xff1a; <div class"child"><div class"test_class">test_class<div class"test1">test1<div class"test2">test2</div></div></div></div>父组件&#xff1a; …

麒麟系统mate_indicators进程占用内存资源高

一、问题现象 故障现象&#xff1a;环境出现内存溢出 操作系统&#xff1a;KYlin10-SP2 二、问题定位 发现mate-indicators进程占用内存资源达到节点总内存40%&#xff0c;导致服务出现内存熔断 临时解决 systemctl restart lightdm.service systemctl set-default multi-u…

使用itextPDF实现PDF电子公章工具类

一、制作公章 在线网站&#xff1a;印章生成器 - Kalvin在线工具 (kalvinbg.cn) 然后对公章进行下载保存 盖章图片&#xff1a; 二、生成数字签名 2.1&#xff1a; java工具keytool生成p12数字证书文件 Keytool是用于管理和证书的工具&#xff0c;位于%JAVA_HOME%/bin目录。…

数学建模----单源最短路径模型建立和求解

目录 1.引言和声明 2.单源最短路径 3.建立模型 4.代码求解 1.引言和声明 &#xff08;1&#xff09;最近又在准备学习matlab,有了一些新的理解和体会&#xff0c;记录一下&#xff1b; &#xff08;2&#xff09;这个首先要声明两个符号&#xff0c;这两个符号也是今天才知…

抖音混剪素材哪里找?可以混剪搬运视频素材网站分享

在抖音上制作精彩的视频离不开高质量的素材资源。今天&#xff0c;我将为大家推荐几个优质的网站&#xff0c;帮助你解决素材短缺的问题。这些网站不仅提供丰富的素材&#xff0c;还符合百度SEO优化的规则&#xff0c;让你的视频更容易被发现。 蛙学府素材网 首先要推荐的是蛙…

AOP切面加自定义注解,实现日志记录

AOP切面加自定义注解&#xff0c;实现日志记录 一、AOP二、准备工作三、添加AOP&#xff0c;把日志保存到数据库 一、AOP 在软件业&#xff0c;AOP为Aspect Oriented Programming的缩写&#xff0c;意为&#xff1a;面向切面编程&#xff0c;通过预编译方式和运行期动态代理实…

IT入门知识博客文章大纲第二部分《编程语言》(2/10)

目录 IT入门知识博客文章大纲第二部分《编程语言》 1.引言 2.编程语言概述 2.1 编程语言的发展历程 2.2 编程范式 3.常见的编程语言 3.1 Python 3.2 Java 3.3 C 3.4 JavaScript 3.5 Ruby 4.编程语言的选择 4.1 技术需求 4.2 团队技能 4.3 社区和生态系统 4.4 可…

3d渲染的类型,渲染100邀请码1a12

3D渲染有不同的类型和方法&#xff0c;它们各有各的优缺点和适用场景&#xff0c;这里我们简单介绍下。 1、离线渲染 离线渲染也被称作预渲染&#xff0c;是指在不考虑时间限制的情况下&#xff0c;生成高质量二维图像或视频的方法。离线渲染通常用于电影、广告、设计等非交互…

【LeetCode】LCR 124. 推理二叉树

题目链接&#xff1a; 题目描述&#xff1a;某二叉树的先序遍历结果记录于整数数组 preorder&#xff0c;它的中序遍历结果记录于整数数组 inorder。请根据 preorder 和 inorder 的提示构造出这棵二叉树并返回其根节点。 注意&#xff1a;preorder 和 inorder 中均不含重复数字…

ESD与EOS区别

最近小白在做项目时&#xff0c;被一个实习生问道了&#xff0c;关于EOS与ESD区别。说实话&#xff0c;以前专注于测试debug的我&#xff0c;在回答对方时&#xff0c;并没法做到太全面的解答。于是乎&#xff0c;借助周内的空闲时间&#xff0c;小白还是简单学习总结了一番。 …

68. UE5 RPG 优化敌人角色的表现效果

我们现在已经有了四个敌人角色&#xff0c;接下来&#xff0c;处理一下在战斗中遇到的问题。 处理角色死亡后还会攻击的问题 因为我们有角色溶解的效果&#xff0c;角色在死亡以后的5秒钟才会被销毁掉。所以在这五秒钟之内&#xff0c;角色其实还是会攻击。主要时因为AI行为树…