大厂面试真题-说一下Mybatis的缓存

首先看一下原理图

Mybatis提供了两种缓存机制:一级缓存(L1 Cache)和二级缓存(L2 Cache),旨在提高数据库查询的性能,减少数据库的访问次数。注意查询的顺序是先二级缓存,再一级缓存。

相关配置

映射文件中的开关(二级缓存的)

一级缓存(L1 Cache)

实现原理

一级缓存是SqlSession级别的缓存,它基于PerpetualCache类实现,该类是Mybatis默认的缓存实现,内部使用HashMap来存储缓存数据。每个SqlSession在创建时都会关联一个Executor,Executor中包含了两个重要的缓存对象:localCachelocalOutputParameterCache(后者主要用于存储过程调用,此处主要讨论localCache)。

BaseExecutor类中,localCache被初始化为PerpetualCache的实例,并存储在Executor对象中。当执行查询操作时,Mybatis会首先检查localCache中是否存在相同的查询(通过CacheKey来唯一标识一个查询),如果存在,则直接从缓存中返回结果;如果不存在,则执行数据库查询,将结果放入localCache中,并返回给调用者。

BaseExecutor类中,可以看到localCache的声明和初始化:

protected PerpetualCache localCache;  
  
protected BaseExecutor(Configuration configuration, Transaction transaction) {  
    // ... 其他初始化代码  
    this.localCache = new PerpetualCache("LocalCache");  
    // ... 其他初始化代码  
}

PerpetualCache类实现了Cache接口,其内部使用HashMap来存储缓存数据:

Executor

概述

Executor是Mybatis中的一个核心接口,它定义了数据库操作的基本方法,如查询(query)、更新(update)、提交(commit)、回滚(rollback)以及清空缓存(clearCache)等。Executor接口的实现类负责具体的SQL执行和缓存管理逻辑。

实现类

  • BaseExecutor:这是一个抽象类,实现了Executor接口的大部分方法,并为子类提供了缓存管理和事务管理的基本功能。子类需要实现doUpdatedoQuerydoQueryCursordoFlushStatements等四个基本方法来完成数据库的相关操作。
  • SimpleExecutor:这是BaseExecutor的一个子类,实现了最基础的SQL执行逻辑,每次执行SQL时都会创建一个新的Statement对象,并不涉及复杂的缓存机制。它是Mybatis的默认执行器。
  • ReuseExecutor:这个执行器实现了Statement的重用功能,它通过内部缓存机制,在同一个SqlSession范围内重用相同的Statement对象,以减少SQL预编译的开销。
  • BatchExecutor:顾名思义,这个执行器用于执行批量操作,它将多个SQL语句打包发送到数据库执行,以减少网络开销和提高性能。
特点与生效条件
  • 作用域:一级缓存是SqlSession级别的缓存,缓存的数据只在当前SqlSession内有效。
  • 默认状态:Mybatis默认开启一级缓存。
  • 生效条件:同一个SqlSession中执行相同的SQL查询时,第一次查询会查询数据库,并将结果存储在缓存中;后续的相同查询则直接从缓存中获取数据,不再访问数据库。
  • 失效条件
    1. 使用不同的SqlSession。
    2. 在同一个SqlSession中,两次查询之间执行了增删改操作(insert、update、delete),这些操作会清空SqlSession中的缓存。
    3. 手动清空了缓存。
    4. 两次查询的查询条件不一致。
应用场景

一级缓存适用于单个SqlSession中的多次相同查询场景,可以有效减少数据库的访问次数,提高查询效率。然而,由于其作用域限制,它不适用于跨SqlSession的查询优化。

二级缓存(L2 Cache)

实现原理

二级缓存是Mapper级别的缓存,它允许多个SqlSession共享缓存数据。二级缓存的开启需要在全局配置文件和Mapper XML文件中进行设置。在Mybatis中,二级缓存是通过Cache接口的实现类来管理的,但Mybatis默认提供了PerpetualCache作为二级缓存的实现。

当二级缓存开启后,Mybatis会为每个Mapper的namespace创建一个独立的缓存区域。当执行查询时,Mybatis会首先检查该Mapper的二级缓存中是否存在相同的查询结果;如果存在,则直接返回缓存中的数据;如果不存在,则执行数据库查询,将结果放入二级缓存中,并返回给调用者。

CachingExecutor

概述

CachingExecutorExecutor的一个实现类,它通过包装其他Executor实现类(如SimpleExecutorReuseExecutorBatchExecutor,这里使用的是装饰器模式),实现了二级缓存机制。它首先检查缓存中是否存在相同查询的结果,如果存在则直接返回缓存中的结果,否则通过被包装的Executor执行查询操作,并将结果存入缓存。

实现步骤

  • 缓存检查:在执行查询操作之前,CachingExecutor会首先检查其管理的二级缓存中是否存在相同查询的结果。这通常通过比较查询的CacheKey来实现,CacheKey是根据查询的SQL语句、参数等信息生成的唯一标识符。
  • 执行查询:如果缓存中不存在相同查询的结果,CachingExecutor会委托给被包装的Executor执行查询操作,并获取查询结果。
  • 缓存结果:将查询结果存入二级缓存中,以便后续相同的查询能够直接从缓存中获取结果。
  • 缓存管理CachingExecutor还负责缓存的清空、提交和回滚等操作,以确保数据的一致性和缓存的有效性。
特点与生效条件
  • 作用域:二级缓存是Mapper级别的缓存,同一个namespace下的所有SqlSession共享这个缓存。
  • 默认状态:Mybatis默认关闭二级缓存,需要手动开启。
  • 开启条件
    1. 在mapper.xml文件中设置<cache/>标签。
    2. 查询数据所转换的实体类类型必须实现序列化接口。
    3. 必须在SqlSession关闭或提交后,才会开启二级缓存。
  • 失效条件
    1. 同一个namespace下的增删改操作会清空缓存。
    2. 缓存超时设置(如果有的话)。
    3. 手动清空缓存。
应用场景
  1. 查询频率高且数据不经常变动的场景:当一个查询被频繁执行,且查询结果很少发生改变时,可以将查询结果缓存在二级缓存中,以提高查询性能。
  2. 多个会话共享相同数据的场景:当多个SqlSession需要共享相同的数据时,可以使用二级缓存来避免重复的数据库查询操作,提高系统性能。
  3. 减轻数据库的负载:在高并发的情况下,数据库可能会成为系统的瓶颈。通过使用二级缓存,可以减轻数据库的负载,提高系统的并发处理能力。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL Performance Schema 详解及运行时配置优化

引言 MySQL 的 Performance Schema 是一套性能监控与诊断工具&#xff0c;帮助开发者和数据库管理员收集、分析 MySQL 实例的运行状态&#xff0c;找出性能瓶颈并进行优化。通过 Performance Schema&#xff0c;我们能够监控不同的内部事件、线程、会话、语句执行等关键性能指…

Java-数据结构-Map和Set-(二)-哈希表 |ू・ω・` )

文本目录&#xff1a; ❄️一、哈希表&#xff1a; ☑ 1、概念&#xff1a; ☑ 2、冲突-概念&#xff1a; ☑ 3、冲突-避免&#xff1a; ☞ 1&#xff09;、避免冲突-哈希函数的设计&#xff1a; ☞ 2&#xff09;、避免冲突-负载因子调节(重点)&#xff1a; ☑ 4、冲突-解决&…

cloud-(Nacos)--注册中心原理-服务注册-服务发现

并且通过(RestTemplate)Http请求实现了跨微服务的远程调用。不过这种手动发送Http请求的方式存在一些问题 在大型微服务项目中,服务提供者的数量会非常多,为了管理这些服务就引入了注册中心的概念。注册中心、服务提供者、服务消费者三者间关系如下: 流程如下: 服务启动…

Mac安装Manim并运行

1.在macOS上创建Python虚拟环境&#xff0c;可以使用venv模块&#xff0c;这是Python自带的库&#xff0c;也可以使用conda。以下是使用venv创建和使用Python虚拟环境的步骤&#xff1a; 打开终端。 创建一个新的目录来存放你的项目&#xff0c;并进入该目录&#xff1a; mk…

15.安卓逆向-frida基础-HOOK类方法1

免责声明&#xff1a;内容仅供学习参考&#xff0c;请合法利用知识&#xff0c;禁止进行违法犯罪活动&#xff01; 内容参考于&#xff1a;图灵Python学院 本人写的内容纯属胡编乱造&#xff0c;全都是合成造假&#xff0c;仅仅只是为了娱乐&#xff0c;请不要盲目相信。 工…

WEB服务器——Tomcat

服务器是可以使用java完成编写&#xff0c;是可以接受页面发送的请求和响应数据给前端浏览器的&#xff0c;而在开发中真正用到的Web服务器&#xff0c;我们不会自己写的&#xff0c;都是使用目前比较流行的web服务器。 如&#xff1a;Tomcat 1. 简介 Tomcat 是一个开源的轻量…

【CAM350】使用总结 <二>{ 光绘Gerber 比较 }

一、 比较两份版本不同的光绘文件&#xff1a; //Analysis-Compare layers// 二、参数默认&#xff0c;比较完成给出结果 三、也可以直接在一份文件上选择“Draw on top” 四、对比差距直观可见

家中浮毛太多怎么办?希喂、米家、安德迈更推荐哪款?

在现代养宠家庭生活中&#xff0c;宠物空气净化器已经成为不可或缺的家电之一。 而在众多空气净化器类型中&#xff0c;宠物空气净化器以其独特的设计和卓越的净化效果&#xff0c;逐渐赢得了越来越多养宠家庭的青睐。 它不仅能有效地吸附空中飞舞的浮毛&#xff0c;还能高效…

基于SSM+小程序的在线课堂微信管理系统(在线课堂1)(源码+sql脚本+视频导入教程+文档)

&#x1f449;文末查看项目功能视频演示获取源码sql脚本视频导入教程视频 1 、功能描述 &emsp1、管理员实现了首页、个人中心、用户管理、课程分类管理、课程信息管理、课程订阅管理、课程视频管理、公告栏管理、留言板管理、系统管理。 2、用户实现了首页、课程信息、公…

此连接非私人连接

当你手机浏览器输入网站打开提示“此连接非私人连接&#xff0c;此网站可能在冒充来窃取你的个人或财务信息。你应回到之前的页面”这是因为该网站的SSL数字证书到期导致&#xff0c;需要此网站的管理员重新申请数字证书替换之前的文件才可以实现。 注意&#xff1a;如果你不是…

实用SQL小总结

WHERE 条件 column 为纯英文字符 或 不包含任何字符 语法&#xff1a; SELECT * FROM your_table WHERE REGEXP(your_column,^[A-Za-z]$); SELECT * FROM your_table WHERE NOT REGEXP(your_column,^[A-Za-z]$);例&#xff1a; SELECT DISTINCT t.pldlibho FROM kibb_pldlyw…

LLM - 使用 vLLM 部署 Qwen2-VL 多模态大模型 (配置 FlashAttention) 教程

欢迎关注我的CSDN&#xff1a;https://spike.blog.csdn.net/ 本文地址&#xff1a;https://spike.blog.csdn.net/article/details/142528967 免责声明&#xff1a;本文来源于个人知识与公开资料&#xff0c;仅用于学术交流&#xff0c;欢迎讨论&#xff0c;不支持转载。 vLLM 用…

02-ZYNQ linux开发环境安装,基于Petalinux2022.2和Vitis2022.2

petalinux安装 Petalinux 工具是 Xilinx 公司推出的嵌入式 Linux 开发套件&#xff0c;包括了 u-boot、Linux Kernel、device-tree、rootfs 等源码和库&#xff0c;以及 Yocto recipes&#xff0c;可以让客户很方便的生成、配置、编译及自定义 Linux 系统。Petalinux 支持 Ver…

uniapp EChars图表

1. uniapp EChars图表 &#xff08;1&#xff09;Apache ECharts 一个基于 JavaScript 的开源可视化图表库   https://echarts.apache.org/examples/zh/index.html &#xff08;1&#xff09;官网图例 &#xff08;2&#xff09;个人实现图例 1.1. 下载echart 1.1.1. 下…

docker - 迁移和备份

文章目录 1、docker commit1.1、查询 容器 docker ps1.2、docker commit zookeeper zookeeper:3.4.13 2、docker save -o2.1、宿主机 切换到 /opt 目录下2.2、将镜像保存到 宿主机/opt目录下 3、docker load -i 对某一个容器修改完毕以后&#xff0c;我们可以把最新的容器部署到…

【文心智能体 | AI大师工坊】如何使用智能体插件,完成一款旅游类智能体的开发,来体验一下我的智能体『​​​​​​​厦门CityWalk』

目录 1.1、智能体运行效果 1.2、创作灵感来源 1.3、如何制作智能体 1.4、可能会遇到的几个问题 1.5、快速调优指南 『厦门CityWalk&#x1f680;』我的优质智能体&#xff1a;https://0nxj3k.smartapps.baidu.com/?_swebfr1&_swebScene3621000000000000 在当今这个全…

Bytebase 2.22.3 - 一键回滚 PostgreSQL DML 变更

&#x1f680; 新功能 支持一键回滚 PostgreSQL DML 变更。 &#x1f384; 改进 优化 DML 事前备份和回滚体验&#xff1a; 引导用户创建 bbdataarchive 数据库。如果没有 bbdataarchive 数据库&#xff0c;无法开启备份功。用户现在可以在创建工单之后开启或关闭备份功能&a…

Python | Leetcode Python题解之第437题路径总和III

题目&#xff1a; 题解&#xff1a; class Solution:def pathSum(self, root: TreeNode, targetSum: int) -> int:prefix collections.defaultdict(int)prefix[0] 1def dfs(root, curr):if not root:return 0ret 0curr root.valret prefix[curr - targetSum]prefix[cu…

ROS学习笔记(四):使用 `ros2 run usb_cam usb_cam_node_exe` 启动 USB 摄像头

文章目录 前言1 安装 usb_cam 包2 启动 USB 摄像头3 订阅相机发布的节点信息并进行可视化3.1 使用 rqt_image_view3.2 使用 image_view3.3 使用 rviz 4 常见问题与解决方案4.1 摄像头未被识别4.2 相机显示异常4.3 如何指定不同的相机4.4 摄像头参数调整 5. 调试信息 5. 结论 前…

9.5K Star,开源在线网盘

Hi&#xff0c;骚年&#xff0c;我是大 G&#xff0c;公众号「GitHub 指北」会推荐 GitHub 上有趣有用的项目&#xff0c;一分钟 get 一个优秀的开源项目&#xff0c;挖掘开源的价值&#xff0c;欢迎关注。 随着云存储的广泛应用&#xff0c;越来越多的人和企业需要一个简单、…