MyBatis 的一级缓存和二级缓存

MyBatis 提供了两种缓存机制,分别是 一级缓存二级缓存。它们可以显著提高数据库操作的性能,通过减少数据库的访问次数,但它们的工作原理、作用范围以及使用方式有所不同。

一、一级缓存

1. 概述

        一级缓存是 SqlSession 级别的缓存,也叫做 本地缓存。它默认开启,并且是 MyBatis 的默认缓存机制。在一次数据库会话(SqlSession)中,MyBatis 会将查询到的结果缓存到一级缓存中。如果相同的 SQL 被多次执行(在同一个 SqlSession 中),MyBatis 会从缓存中读取数据,而不去数据库中查询,这样可以减少数据库的访问。

2. 特点

  • 作用范围:一级缓存的作用范围仅限于一个 SqlSession 实例,也就是说,每个 SqlSession 都有独立的一级缓存。
  • 缓存失效:在同一个 SqlSession 中,只要没有提交、回滚或关闭 SqlSession,缓存的数据都是有效的。执行 commit() 或 rollback() 后,一级缓存会被清空,缓存的内容会失效。
  • 缓存内容:一级缓存存储的是 SqlSession 中执行的查询结果。例如,对于一个查询语句,第一次查询会执行数据库操作,将结果存入缓存,之后相同的查询会直接从缓存中返回,而无需再次查询数据库。

3. 示例

// 获取 SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();// 第一次查询,将会访问数据库
User user1 = sqlSession.selectOne("namespace.selectUser", 1);// 第二次查询(相同 SQL 和参数),此时数据会从一级缓存中获取
User user2 = sqlSession.selectOne("namespace.selectUser", 1);System.out.println(user1 == user2);  // true,因为是同一个 SqlSession 对象

4. 清空一级缓存

  • 调用 sqlSession.clearCache() 手动清空缓存。
  • 调用 commit() 或 rollback(),这些操作也会清空一级缓存。

二、二级缓存

1. 概述

二级缓存是 SqlSessionFactory 级别的缓存,也叫做 全局缓存。它在 MyBatis 的多个 SqlSession 之间共享缓存数据。换句话说,二级缓存的数据是跨 SqlSession 存在的,可以共享缓存内容。

2. 特点

  • 作用范围:二级缓存是跨 SqlSession 的,所有使用同一个 SqlSessionFactory 创建的 SqlSession 都可以共享这个缓存。也就是说,二级缓存是全局缓存,能够跨会话存储查询结果。
  • 缓存失效:二级缓存会在 SqlSessionFactory 被销毁时失效。如果 SqlSessionFactory 被关闭,二级缓存中的数据会被清空。
  • 配置与使用:二级缓存需要在 MyBatis 配置文件中显式启用,并且每个映射器(Mapper)都可以单独配置是否启用二级缓存。

3. 如何启用二级缓存

  1. 在 MyBatis 配置文件中启用二级缓存
    <configuration><settings><setting name="cacheEnabled" value="true"/></settings>
    </configuration>
    
  2. 在 Mapper 文件中启用二级缓存: 每个 Mapper 都可以单独配置是否启用二级缓存,通常在 Mapper XML 中进行配置。
    <mapper namespace="com.example.mapper.UserMapper"><!-- 启用二级缓存 --><cache /><select id="selectUser" resultType="User">SELECT * FROM users WHERE id = #{id}</select>
    </mapper>
    
  3. 二级缓存的存储方式: 二级缓存通常使用内存存储查询结果,但它也可以通过自定义缓存实现,支持持久化缓存。默认情况下,MyBatis 使用 PerpetualCache 类作为二级缓存实现,也可以通过配置缓存实现类来替换。

4. 二级缓存的工作原理

  1. 查询数据:当一个查询被执行时,MyBatis 会先检查二级缓存中是否已有该数据。如果没有,MyBatis 会执行 SQL 查询,将结果存入缓存,并返回查询结果。
  2. 使用缓存:在随后的查询中,如果该数据存在于二级缓存中,MyBatis 会直接返回缓存中的数据,避免再次查询数据库。
  3. 缓存更新:当执行更新、删除等操作时,相关缓存会被清除或更新。这是为了确保缓存中的数据始终是最新的。

5. 清除二级缓存

  • 手动清空缓存:通过调用 sqlSession.clearCache() 来清空一级缓存,但二级缓存依赖于 SqlSessionFactory,不会自动清空。
  • 执行增删改操作时清空:对于增、删、改等操作,MyBatis 会自动清空相关的二级缓存,确保缓存中的数据是一致的。

6. 示例

// 获取 SqlSession
SqlSession sqlSession1 = sqlSessionFactory.openSession();
User user1 = sqlSession1.selectOne("namespace.selectUser", 1);
sqlSession1.commit();  // 提交会话,一级缓存清空// 获取另一个 SqlSession,查询将使用二级缓存
SqlSession sqlSession2 = sqlSessionFactory.openSession();
User user2 = sqlSession2.selectOne("namespace.selectUser", 1);
System.out.println(user1 == user2);  // true,数据来自二级缓存

7. 二级缓存与事务的关系

  • 在执行增、删、改等写操作时,相关的二级缓存会被清空。这样可以确保修改后的数据不会因缓存而导致不一致。
  • 由于 MyBatis 的事务机制是基于 SqlSession 的,所以在同一事务中的不同 SqlSession 共享的二级缓存会在事务提交时清空。

8. 二级缓存的生命周期

  • 二级缓存会在 SqlSessionFactory 被销毁时失效,通常在应用程序停止时,MyBatis 会销毁 SqlSessionFactory 实例,二级缓存也会清空。

三、总结 

  • 一级缓存 是 SqlSession 局部的缓存,每个 SqlSession 都有自己的缓存,默认启用。它会在同一个会话内缓存查询结果,避免重复查询数据库。
  • 二级缓存 是跨 SqlSession 的全局缓存,多个 SqlSession 可以共享缓存的内容,适用于跨会话的缓存。二级缓存需要在 MyBatis 配置文件和 Mapper 文件中显式启用。
  • 缓存清空机制:一级缓存会在事务提交、回滚或手动清空时清空,而二级缓存则会在修改数据时自动清空相关缓存,保持数据一致性。

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

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

相关文章

数据结构之栈,队列,树

目录 一.栈 1.栈的概念及结构 2.栈的实现 3.实现讲解 1.初始化栈 2.销毁栈 3.压栈 4.出栈 5.返回栈顶元素 6.返回栈内元素个数 7.判断栈内是否为空 二.队列 1.队列的概念及结构 2.队列的实现 3.实现讲解 1.初始化队列 2.销毁队列 3.单个成员入队列 4.单个成员…

2、C#基于.net framework的应用开发实战编程 - 设计(二、三) - 编程手把手系列文章...

二、设计&#xff1b; 二&#xff0e;三、构建数据库&#xff1b; 此例子使用的是SQLite数据库&#xff0c;所以数据库工具用的SQLiteStudio x64&#xff0c;这个是SQLite专用的数据库设计管理工具&#xff0c;其它的数据库管理工具比如DBeaver的使用请见实战工具系列文章。 1、…

“信任构建”:网上购物商城的用户评价与信誉系统

2 相关技术 2.1 SSM框架介绍 本课题程序开发使用到的框架技术&#xff0c;英文名称缩写是SSM&#xff0c;在JavaWeb开发中使用的流行框架有SSH、SSM、SpringMVC等&#xff0c;作为一个课题程序采用SSH框架也可以&#xff0c;SSM框架也可以&#xff0c;SpringMVC也可以。SSH框架…

单点Redis所面临的问题及解决方法

1.数据丢失问题 大家可以设想一下这个场景&#xff0c;假如我们现在只有一个Redis&#xff0c;即单点Redis&#xff0c;我们在往Redis中添加数据的时候突然宕机了&#xff0c;那数据怎么办&#xff0c;如果是一条还好&#xff0c;我在敲一遍就行&#xff0c;那我敲了一万行都没…

计算机组成原理的学习笔记(8)-- 指令系统·其一 指令的组成以及数据寻址方式

学习笔记 前言 ​ 本文主要是对于b站尚硅谷的计算机组成原理的学习笔记&#xff0c;仅用于学习交流。 1. 指令 1.1 组成 操作码&#xff08;Opcode&#xff09;&#xff1a;指指令中执行特定操作的部分。地址码&#xff1a;指令中用于指定操作数位置的部分。 1.2 扩展操作…

RAGFlow 基于深度文档理解构建的开源 RAG引擎 - 安装部署

RAGFlow 基于深度文档理解构建的开源 RAG引擎 - 安装部署 flyfish 1. 确保 vm.max_map_count ≥ 262144 这是指要调整Linux内核参数vm.max_map_count&#xff0c;以确保其值至少为262144。这个参数控制着进程可以映射的最大内存区域数量。对于某些应用程序&#xff08;如Ela…

2024.2 ACM Explainability for Large Language Models: A Survey

Explainability for Large Language Models: A Survey | ACM Transactions on Intelligent Systems and Technology 问题 可解释性问题&#xff1a;大语言模型&#xff08;LLMs&#xff09;内部机制不透明&#xff0c;难以理解其决策过程&#xff0c;如在自然语言处理任务中&…

docker与docker-compose版本对应

1、说明 docker 和 docker-compose 是两个独立但又紧密相关的工具&#xff0c;docker用于管理docker容器&#xff0c;docker-compose用于编排多docker容器应用。了解它们之间的版本对应关系有助于确保在使用 docker-compose 时不会遇到兼容性问题。 2、docker与docker-compos…

【动态规划篇】步步带你深入解答成功AC最优包含问题(通俗易懂版)

本篇小鸡汤&#xff1a;待到苦尽甘来时&#xff0c;我给你讲讲来时路。 欢迎拜访&#xff1a;羑悻的小杀马特.-CSDN博客 本篇主题&#xff1a;解答洛谷的最优包含问题 制作日期&#xff1a;2024.12.23 隶属专栏&#xff1a;C/C题海汇总 ​​ 目录 本篇简介&#xff1a; 一动态…

Intent--组件通信

组件通信1 获取子活动的返回值 创建Activity时实现自动注册&#xff01;【Activity必须要注册才能使用】 默认 LinearLayout 布局&#xff0c;注意 xml 中约束布局的使用&#xff1b; 若需要更改 线性布局 只需要将标签更改为 LinearLayout 即可&#xff0c;记得 设置线性布局…

table 表格转成 excell 导出

OK&#xff0c;功能非常简单&#xff0c;但是很实用啊&#xff01; 依赖安装 这里我们需要安装两个依赖&#xff1a; xlsx 和 file-saver&#xff0c;就可以帮助我们实现功能了&#xff01; npm i xlsx file-saver代码参考 导出方法 utils/index.js import * as XLSX from …

Vivado 编译(单核性能对比+高性能迷你主机+Ubuntu20.04/22.04安装与区别+20.04使用远程命令)

目录 1. 简介 2. 单核性能对比 2.1 PassMark 2.2 geekbench 2.3 CPU-7 2.4 选择 UM790 pro 3. Ubuntu 22.04 物理机 3.1 安装 Ubuntu 22.04 3.2 安装 Vitis 2022.1 3.3 缺点 4. Ubuntu 20.04 物理机 4.1 安装 Ubuntu 20.04 4.2 实用命令 4.2.1 SSH 保持活跃 4.2…

Java期末复习JDBC|网课笔记+校课总结

目录 1、概念 2、JDBC步骤 JDBC的基本步骤&#xff1a; 1、加载数据库驱动&#xff1a;通常使用Class类的forName()静态方法来加载驱动。 2、通过DriverManager获取数据库连接&#xff1a;需要传入3个参数&#xff1a;数据库URL、登陆数据库的用户名和密码。 3、通过Conn…

Require:离线部署 Sourcegraph

Sourcegraph 使读取、编写和修复代码变得容易——即使在庞大而复杂的代码库中。 代码搜索&#xff1a;搜索所有分支和所有代码主机的所有存储库。代码智能&#xff1a;导航代码、查找引用、查看代码所有者、跟踪历史记录等。修复和重构&#xff1a;一次对许多存储库进行大规模更…

element ui--下拉根据拼音首字母过滤

很多场景下我们的下拉不仅仅要根据选项中的字过滤&#xff0c;还要根据拼音首字母过滤&#xff0c;现在我们来实现下。 要获取汉字拼音&#xff0c;可以用pinyin-pro库来实现 1.导入拼音库 npm install pinyin-pro 下面的代码可以获取companyName的拼音&#xff0c;返回的是…

Vue3 中使用axios

1.安装axios、js-cookie、pinia axios命令行&#xff1a; npm install axios js-cookie命令行&#xff1a; npm install js-cookie store命令行&#xff1a; npm install pinia 2.配置文件 (1)缓存文件配置 src/plugins/auth.js const sessionCache {set (key, valu…

从AI换脸到篡改图像,合合信息如何提升视觉内容安全?

本文目录 引言一、AI“真假之战”下的发展现状与考验挑战1.1 视觉内容安全现状与技术分类1.2视觉内容安全企业1.3视觉内容安全领域挑战 二、开山之石&#xff1a;引领视觉内容安全的创新之路2.1合合内容安全系统2.2发起编制相关技术规范2.3参与篡改检测挑战赛 三、视觉内容安全…

解决Ubuntu下无法装载 Windows D盘的问题

电脑安装了 Windows 和 Ubuntu 24.04 后&#xff0c;在Ubuntu系统上装载 D盘&#xff0c;发现无法装载错误如下&#xff1a; Error mounting /dev/nvme0n1p4 at /media/jackeysong/Data: wrong fs type, bad option, bad superblock on /dev/nvme0n1p4, missing codepage or h…

STM32-笔记10-手写延时函数(SysTick)

1、什么是SysTick Systick&#xff0c;即滴答定时器&#xff0c;是内核中的一个特殊定时器&#xff0c;用于提供系统级的定时服务。该定时器是一个24位的倒计数定时器‌。它从设定的初值&#xff08;即重载值&#xff09;开始计数&#xff0c;每经过一个系统时钟周期&#xff0…

“AI+Security”系列第4期(一)之“洞” 见未来:AI 驱动的漏洞挖掘新范式

在数字化浪潮下&#xff0c;安全漏洞问题日益严峻&#xff0c;成为各行业发展的重大挑战。近日&#xff0c;“AISecurity” 系列第 4 期线下活动于北京成功举办&#xff0c;聚焦 “洞” 见未来&#xff1a;AI 驱动的漏洞挖掘新范式&#xff0c;汇聚了安全领域的众多专家。 本次…