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,一经查实,立即删除!

相关文章

压缩qcow2镜像带来的性能损失简单分析

本文拟对压缩qcow2镜像所带来的虚拟机性能损失进行简单分析 背景 生产中发现使用压缩镜像启动的虚拟机开机总是会慢一些。 qcow2镜像的压缩方式为&#xff1a;qemu-img convert -p -c -O qcow2 zero_disk.qcow2 compress_disk.qcow2 分析 qemu代码&#xff1a;https://down…

数据结构之栈,队列,树

目录 一.栈 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框架…

云技术基础

声明&#xff01; 学习视频来自B站up主 **泷羽sec** 有兴趣的师傅可以关注一下&#xff0c;如涉及侵权马上删除文章&#xff0c;笔记只是方便各位师傅的学习和探讨&#xff0c;文章所提到的网站以及内容&#xff0c;只做学习交流&#xff0c;其他均与本人以及泷羽sec团队无关&…

单点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 扩展操作…

汇总贴:cocos creator

1 cocoscreator-doc-TS:目录-CSDN博客 访问节点和组件 常用节点和组件接口 创建和销毁节点 加载和切换场景 获取和设置资源 监听和发射事件 节点系统事件 缓动系统&#xff08;cc.tween&#xff09; 使用计时器 使用对象池 使用 TypeScript 脚本 模块化脚本 脚本执行顺序 全局…

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…

【Nginx系列】---Nginx配置tcp转发

参考 Nginx 配置文件&#xff1a; error_log /var/log/nginx/error.log notice; pid /var/run/nginx.pid;events {worker_connections 1024; }stream {# 第一个服务转发upstream mysqltest {server 172.16.187.142:9000;}server {listen 9000;proxy_pass mysqltest;}…

Micropython RPI-PICO 随记-DS3231和RTC

开发环境 MCU&#xff1a;Pico1&#xff08;无wifi版&#xff09;时钟模块&#xff1a;DS3231使用固件&#xff1a;自编译版本开发环境&#xff1a;MacBook Pro Sonoma 14.5开发工具&#xff1a;Thonny 4.1.6开发语言&#xff1a;MicroPython 1.24.0 知识记录 DS3231是一款高…

SQLSERVER、MYSQL LIKE查询特殊字符和转义字符相同与不同

SQL Server 和 MySQL 都支持 LIKE 操作符进行模式匹配&#xff0c;但它们在处理特殊字符和转义字符方面有一些差异。尽管两者有很多相似之处&#xff0c;但在某些细节上并不完全通用。以下是 SQL Server 和 MySQL 在 LIKE 操作符使用上的比较&#xff1a; 通配符 百分号 %&am…

【动态规划篇】步步带你深入解答成功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 …

python file seek tell

Python面试题解析丨Python实现tail -f功能 文件指针定位之 seek 方法 seek(offset, from) offset &#xff1a;文件指针偏移量(很多博客在这里将offset定义为指针偏移量&#xff0c;但是目前我的看法是这里定义为指针的相对位置) from &#xff1a; 0-文件开头 1-当前位置 2-文…

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…