介绍一下Mybatis的底层原理(包括一二级缓存)

news2025/2/6 2:46:13

表面上我们的就是Sql语句和我们的java对象进行映射,然后Mapper代理然后调用方法来操作数据库

底层的话我们就涉及到Sqlsession和Configuration

首先说一下SqlSession, 它可以被视为与数据库交互的一个会话,用于执行 SQL 语句(Executor执行器)获取映射器(Mapper)管理事务等操作

然后还有个全局配置Configuration,Configuration是Mybatis的核心配置类,里面有所有的配置信息,映射文件内容,甚至数据库连接池配置

SqlSession

也就是说我们的通过SqlSession来操作我们的数据库,SqlSession里面的执行器Executor来执行我们的具体的sql语句

我们的Executor其实有三种SimpleExecutor简单执行器,ReuseExecutor可重用执行器, BatchExecutor批量执行器

一个是每次使用都创建一个Statement对象,一个是可以以sql作为Key在Map<String,Statement>内查找我们的statement对象进行重用,一个是将所有的sql语句添加到批处理等待逐一执行

Configuration

很简单,就是一个mybatis的核心配置类,我们的主要的配置信息例如数据库连接池配置就在里面

再深入一点就讲一下我们的Mybatis的一二级缓存实现原理

一级缓存(在Sqlsession对象了里面):

我们有的话就用Executor执行器,从LocalCache里面查询,没有的话就从数据库中查然后放到我们的LocalCache里面

在分布式或者多个Sqlsession的情况下,可能会导致脏读问题

我们查询的时候会从Sqlsession的缓存里面查,那要是我们此时用SqlSession1和SqlSession2,我们要的数据在SqlSession2的缓存里面怎么办?我们一级缓存不能实现跨SqlSession,只能查不到然后查数据库

所以为了进一步优化多个SqlSession问题,我们就有了二级缓存

二级缓存(在Configuration里面):

在一级缓存查询之前,我们先通过CachingExecutor从二级缓存中进行查询

开启二级缓存之后呢,会被多个Sqlsession共享,所以它是一个全局的缓存

所以查询流程变成了:先查二级缓存,再查一级缓存,再查数据库

二级缓存对比一级缓存,它实现了Sqlsession之间的缓存数据的共享


既然二级缓存可以优化查询?那为什么不默认用二级缓存?

数据一致性问题

  • 问题描述:二级缓存是跨SqlSession的,多个SqlSession共享同一个缓存。如果某个SqlSession更新了数据库,其他SqlSession可能仍然使用缓存中的旧数据,导致数据不一致。
  • 解决方案:可以通过配置缓存的刷新策略(如flushInterval)或在更新操作后手动清除缓存来缓解。

2. 缓存失效问题

  • 问题描述:当执行增删改操作时,MyBatis会清除相关缓存。但如果其他系统或程序直接修改了数据库,MyBatis无法感知,导致缓存中的数据与实际数据库不一致
  • 解决方案:需要结合其他机制(如数据库触发器或消息队列)来通知缓存失效。

3. 内存占用问题

  • 问题描述:二级缓存默认存储在内存中,如果缓存的数据量过大,可能导致内存溢出(OOM)
  • 解决方案:可以通过配置缓存实现(如Ehcache、Redis)将缓存存储到磁盘或分布式缓存中。

4. 序列化问题

  • 问题描述二级缓存默认需要缓存对象实现Serializable接口以便序列化存储。如果对象未实现序列化接口,会导致缓存失败。
  • 解决方案:确保所有缓存对象实现Serializable接口,或使用自定义的缓存实现。

5. 缓存粒度问题

  • 问题描述:二级缓存的粒度是Mapper级别的,即一个Mapper的缓存会被所有查询共享。如果某个Mapper的查询结果差异较大,可能导致缓存命中率低,甚至缓存污染
  • 解决方案:可以通过自定义缓存键或使用更细粒度的缓存策略来优化。

6. 分布式环境下的问题

  • 问题描述:在分布式环境中,默认的二级缓存是本地缓存,不同节点之间的缓存无法共享,可能导致数据不一致。
  • 解决方案:使用分布式缓存(如Redis、Memcached)替换默认的本地缓存。

7. 缓存配置复杂

  • 问题描述:二级缓存的配置相对复杂,需要根据业务场景调整缓存策略(如缓存清除策略、缓存刷新间隔等),配置不当可能导致性能下降或数据不一致。
  • 解决方案:仔细评估业务需求,合理配置缓存参数。

8. 不适合高并发写场景

  • 问题描述:在高并发写场景下,频繁的增删改操作会导致缓存频繁失效反而降低性能
  • 解决方案:在高并发写场景下,建议禁用二级缓存,或使用更高效的缓存策

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

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

相关文章

WordPress使用(1)

1. 概述 WordPress是一个开源博客框架&#xff0c;配合不同主题&#xff0c;可以有多种展现方式&#xff0c;博客、企业官网、CMS系统等&#xff0c;都可以很好的实现。 官网&#xff1a;博客工具、发布平台和内容管理系统 – WordPress.org China 简体中文&#xff0c;这里可…

BUUCTF_[安洵杯 2019]easy_web(preg_match绕过/MD5强碰撞绕过/代码审计)

打开靶场&#xff0c;出现下面的静态html页面&#xff0c;也没有找到什么有价值的信息。 查看页面源代码 在url里发现了img传参还有cmd 求img参数 这里先从img传参入手&#xff0c;这里我发现img传参好像是base64的样子 进行解码&#xff0c;解码之后还像是base64的样子再次进…

C基础寒假练习(4)

输入带空格的字符串&#xff0c;求单词个数、 #include <stdio.h> // 计算字符串长度的函数 size_t my_strlen(const char *str) {size_t len 0;while (str[len] ! \0) {len;}return len; }int main() {char str[100];printf("请输入一个字符串: ");fgets(…

MySQL 事务实现原理( 详解 )

MySQL 主要是通过: 锁、Redo Log、Undo Log、MVCC来实现事务 事务的隔离性利用锁机制实现 原子性、一致性和持久性由事务的 redo 日志和undo 日志来保证。 Redo Log(重做日志)&#xff1a;记录事务对数据库的所有修改&#xff0c;在崩溃时恢复未提交的更改&#xff0c;保证事务…

git基础使用--1--版本控制的基本概念

文章目录 git基础使用--1--版本控制的基本概念1.版本控制的需求背景&#xff0c;即为啥需要版本控制2. 集中式版本控制SVN3. 分布式版本控制 Git4. SVN和Git的比较 git基础使用–1–版本控制的基本概念 1.版本控制的需求背景&#xff0c;即为啥需要版本控制 先说啥叫版本&…

Unity飞行代码 超仿真 保姆级教程

本文使用Rigidbody控制飞机&#xff0c;基本不会穿模。 效果 飞行效果 这是一条优雅的广告 如果你也在开发飞机大战等类型的飞行游戏&#xff0c;欢迎在主页搜索博文并参考。 搜索词&#xff1a;Unity游戏(Assault空对地打击)开发。 脚本编写 首先是完整代码。 using System.Co…

力扣73矩阵置零

给定一个 m x n 的矩阵&#xff0c;如果一个元素为 0 &#xff0c;则将其所在行和列的所有元素都设为 0 。请使用 原地 算法。 输入&#xff1a;matrix [[1,1,1],[1,0,1],[1,1,1]] 输出&#xff1a;[[1,0,1],[0,0,0],[1,0,1]] 输入&#xff1a;matrix [[0,1,2,0],[3,4,5,2],[…

登录认证(5):过滤器:Filter

统一拦截 上文我们提到&#xff08;登录认证&#xff08;4&#xff09;&#xff1a;令牌技术&#xff09;&#xff0c;现在大部分项目都使用JWT令牌来进行会话跟踪&#xff0c;来完成登录功能。有了JWT令牌可以标识用户的登录状态&#xff0c;但是完整的登录逻辑如图所示&…

python算法和数据结构刷题[1]:数组、矩阵、字符串

一画图二伪代码三写代码 LeetCode必刷100题&#xff1a;一份来自面试官的算法地图&#xff08;题解持续更新中&#xff09;-CSDN博客 算法通关手册&#xff08;LeetCode&#xff09; | 算法通关手册&#xff08;LeetCode&#xff09; (itcharge.cn) 面试经典 150 题 - 学习计…

详解u3d之AssetBundle

一.AssetBundle的概念 “AssetBundle”可以指两种不同但相关的东西。 1.1 AssetBundle指的是u3d在磁盘上生成的存放资源的目录 目录包含两种类型文件(下文简称AB包)&#xff1a; 一个序列化文件&#xff0c;其中包含分解为各个对象并写入此单个文件的资源。资源文件&#x…

接口测试通用测试用例

接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。 测试的重点是检查数据的交换&#xff0c;传递和控制管理过程&#xff0c;以及系统间的相互逻辑依赖关系等。 现在很多系统前后端架构是分离的&#xff0c;从安全层面来说&#xff0c;只依赖前段进行限…

【BUUCTF杂项题】荷兰宽带数据泄露、九连环

一.荷兰宽带数据泄露 打开发现是一个.bin为后缀的二进制文件&#xff0c;因为提示宽带数据泄露&#xff0c;考虑是宽带路由器方向的隐写 补充&#xff1a;大多数现代路由器都可以让您备份一个文件路由器的配置文件&#xff0c;软件RouterPassView可以读取这个路由配置文件。 用…

蓝桥杯思维训练营(三)

文章目录 题目详解680.验证回文串 II30.魔塔游戏徒步旅行中的补给问题观光景点组合得分问题 题目详解 680.验证回文串 II 680.验证回文串 II 思路分析&#xff1a;这个题目的关键就是&#xff0c;按照正常来判断对应位置是否相等&#xff0c;如果不相等&#xff0c;那么就判…

基于RTOS的STM32游戏机

1.游戏机的主要功能 所有游戏都来着B站JL单片机博主开源 这款游戏机具备存档与继续游戏功能&#xff0c;允许玩家在任何时候退出当前游戏并保存进度&#xff0c;以便日后随时并继续之前的冒险。不仅如此&#xff0c;游戏机还支持多任务处理&#xff0c;玩家可以在退出当前游戏…

计算机网络——三种交换技术

目录 电路交换——用于电话网络 电路交换的优点&#xff1a; 电路交换的缺点&#xff1a; 报文交换——用于电报网络 报文交换的优点&#xff1a; 报文交换的缺点&#xff1a; 分组交换——用于现代计算机网络 分组交换的优点&#xff1a; 分组交换的缺点 电路交换——…

HTML5教程之标签(2)

HTML5 <b> 标签 实例 在HTML5中&#xff0c;你可以使用<b>标签来对某些文本实现加粗的效果&#xff0c;请参考下述的示例&#xff1a; <p>这是一个普通的文本- <b>这是一个加粗文本</b>。</p> 尝试一下 浏览器支持 所有主流浏览器都支…

Verilog基础(一):基础元素

verilog基础 我先说,看了肯定会忘,但是重要的是这个过程,我们知道了概念,知道了以后在哪里查询。语法都是术,通用的概念是术。所以如果你有相关的软件编程经验,那么其实开启这个学习之旅,你会感受到熟悉,也会感受到别致。 入门 - 如何开始 欢迎来到二进制的世界,数字…

Vue 图片引用方式详解:静态资源与动态路径访问

目录 前言1. 引用 public/ 目录2. assets/ 目录3. 远程服务器4. Vue Router 动态访问5. 总结6. 扩展&#xff08;图片不显示&#xff09; 前言 &#x1f91f; 找工作&#xff0c;来万码优才&#xff1a;&#x1f449; #小程序://万码优才/r6rqmzDaXpYkJZF 在 Vue 开发中&#x…

Qt网络相关

“ 所有生而孤独的人&#xff0c;葆有的天真 ” 为了⽀持跨平台, QT对⽹络编程的 API 也进⾏了重新封装。本章会上手一套基于QT的网络通信编写。 UDP Socket 在使用Qt进行网络编程前&#xff0c;需要在Qt项目中的.pro文件里添加对应的网络模块( network ). QT core gui net…

生成式AI安全最佳实践 - 抵御OWASP Top 10攻击 (上)

今天小李哥将开启全新的技术分享系列&#xff0c;为大家介绍生成式AI的安全解决方案设计方法和最佳实践。近年来&#xff0c;生成式 AI 安全市场正迅速发展。据 IDC 预测&#xff0c;到 2025 年全球 AI 安全解决方案市场规模将突破 200 亿美元&#xff0c;年复合增长率超过 30%…