MyBatis缓存详解(一级缓存、二级缓存、缓存查询顺序)

固态硬盘缺陷:无法长时间使用,而磁盘只要不消磁,只要不受到磁影响,就可以长期使用,因此绝大多数企业还是使用磁盘来存储数据

像mysql这种关系型数据库中的数据存储在磁盘中,为方便查询,减少系统开销,提高查询效率,会在内存中开辟空间用于存储经常查询、但不怎么改变的数据,这块空间称为缓存
在这里插入图片描述
MyBatis缓存分类

  1. 一级缓存
  2. 二级缓存

前置知识,MyBatis是如何执行的

private InputStream in = null;private SqlSession session = null;private UserDao mapper = null;@Before  //前置通知, 在方法执行之前执行public void init() throws IOException {//加载主配置文件,目的是为了构建SqlSessionFactory对象in = Resources.getResourceAsStream("SqlMapConfig.xml");//创建SqlSessionFactory对象SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);//通过SqlSessionFactory工厂对象创建SqlSesssion对象session = factory.openSession();//通过Session创建UserDao接口代理对象mapper = session.getMapper(UserDao.class);}@After  //@After: 后置通知, 在方法执行之后执行 。public void destory() throws IOException {//释放资源session.close();in.close();}
}

在这里插入图片描述

1.一级缓存

默认情况下开启的缓存 放在SqlSession对象中

什么是对象→堆里面的一块内存空间

上述的SqlSession对象也是堆里面的一块空间,SqlSession对象里有一块一级缓存空间(SqlSession对象所在空间∈内存,cache缓存所在空间∈SqlSession对象所在空间,因此,之前说缓存是内存中的一块空间)
在这里插入图片描述
两次查询同一个数据,sql语句只会执行一次,第二次会从缓存中直接获取数据

@Testpublic void findById(){User user1 = mapper.findById(1);User user2 = mapper.findById(1);System.out.println(user1.toString());System.out.println(user2.toString());System.out.println(user1 == user2);  //在引用数据类型当中 == 是用来比较什么的? 是否指向同一个内存地址}

在这里插入图片描述

一级缓存失效的四种情况

1.sqlSession不同

一个SqlSession可以生成多个session对象,继而创建多个mapper

private InputStream in = null;private SqlSession session = null;private SqlSession session2 = null;private UserDao mapper = null;private UserDao mapper2 = null;@Before  //前置通知, 在方法执行之前执行public void init() throws IOException {//加载主配置文件,目的是为了构建SqlSessionFactory对象in = Resources.getResourceAsStream("SqlMapConfig.xml");//创建SqlSessionFactory对象SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);//通过SqlSessionFactory工厂对象创建SqlSesssion对象session = factory.openSession();session2 = factory.openSession();//通过Session创建UserDao接口代理对象mapper = session.getMapper(UserDao.class);mapper2 = session2.getMapper(UserDao.class);}@After  //@After: 后置通知, 在方法执行之后执行 。public void destory() throws IOException {//释放资源session.close();in.close();}/** sqlSession不同* 两个mapper不是同一个session生成的,故对应的开辟的内存空间也不同* */@Testpublic void findById5(){User user1 = mapper.findById(1);User user2 = mapper2.findById(1);System.out.println(user1 == user2);}
}

在这里插入图片描述
两个mapper不是同一个session生成的,故对应的开辟的内存空间也不同

2.sqlSession相同,查询条件不同,多次查询不同的情况,不会导致缓存失效

其实也很好理解,第一次查询的数据存储在缓存中,但第二次查询查询的是与第一次不同的数据,那缓存中必然是没有第二次查询的数据的

 /*sqlSession相同,查询条件不同*/@Testpublic void findById1(){User user1 = mapper.findById(1);User user2 = mapper.findById(2);System.out.println(user1.toString());System.out.println(user2.toString());System.out.println(user1 == user2);}

在这里插入图片描述
3.sqlSession相同,查询的数据也相同,但两次查询之间执行了增删改操作

缓存要和数据库保持一致,如果进行了增删改操作却不修改缓存,那么可能造成缓存和数据库不一致的情况,所以执行增删改操作后缓存便失效了

/*** sqlSession相同,查询的数据也相同,但两次查询之间执行了增删改操作* 缓存要和数据库保持一致,如果进行了增删改操作不修改缓存,那么可能造成缓存和数据库不一致的情况!*/@Testpublic void findById2(){User user1 = mapper.findById(1);mapper.insert(user1); //两次查询之间执行了增删改操作!User user2 = mapper.findById(1);System.out.println(user1 == user2);}

在这里插入图片描述
4.sqlSession相同,手动清除一级缓存

/** sqlSession相同,手动清除一级缓存* */@Testpublic void findById3(){User user1 = mapper.findById(1);session.clearCache(); //清除缓存User user2 = mapper.findById(1);System.out.println(user1 == user2);}

session.clearCache()
在这里插入图片描述
这个也很好理解,第一次查询后缓存被清除了,第二次查询相同的数据时,缓存中已经没有了相应的数据,必然是要重新执行sql语句进行查询,开辟了新的内存空间,故指向地址也不一致了

2.二级缓存

二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactroy创建SqlSession查询结果会被缓存;此后若再次执行相同的查询语句,结果会从一个缓存中获取。

(1)二级缓存开启的条件

①:在核心配置文件中,设置全局属性caheEnabled="true"

②:在mapper映射文件中配置<cache/>

③:查询数据所转换的实体类类型必须实现序列化接口 implements Serializable

④:二级缓存必须在SqlSession(一级缓存)关闭或提交之后有效

(2)开启二级缓存

①.在SqlMapConfig.xml配置文件中开启二级缓存

<!‐‐ 开启二级缓存 ‐‐>
<settings><!--开启二级缓存--><setting name="cacheEnabled" value="true"/>
</settings>

②. 在UserMapper.xml配置文件声明使用二级缓存

<!--使用二级缓存--><cache/>

③:查询数据所转换的实体类类型必须实现序列化接口

public class User  implements Serializable{......
}

④:二级缓存必须在SqlSession关闭或提交之后有效

@Testpublic void findById4(){User user1 = mapper.findById(1);//关闭一级缓存session.close();User user2 = mapper2.findById(1);session2.close();System.out.println(user1 == user2);   // 一级缓存缓存的是对象,二级缓存缓存的是数据}

在这里插入图片描述
打印发现2个对象的地址值不一样,但是确实只发送了一次SQL语句的查询,二级缓存中存储的是数据,不是对象

一级缓存缓存的是对象(俩对象地址相同则相等),而二级缓存缓存的是数据,数据无法直接对比是否相同,故为false

(3)二级缓存失效的情况

两次查询之间行了任意的增删改,会使得一级二级缓存同时失效

这点与一级缓存一致,故不再赘述

(4)Catch参数的具体细节

缓存空间也是有限的,当满了之后,再进来新的数据,就要将之前的数据进行移除

eviction(收回策略)

  • LRU(最近最少使用的):移除最长时间不被使用的对象,这是默认值。
  • FIFO(先进先出):按对象进入缓存的顺序来移除它们。
  • SOFT(软引用):移除基于垃圾回收器状态和软引用规则的对象。
  • WEAK(弱引用):更积极地移除基于垃圾收集器状态和弱引用规则的对象。

flushinterval(刷新间隔)

可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。

  • 默认情况不设置,即没有刷新间隔,缓存仅仅在调用语句时刷新。

size(引用数目)

  • 可以被设置为任意正整数,要记住缓存的对象数目和运行环境的可用内存资源数目。默认值是1024 。

readOnly(只读)

属性可以被设置为 true / false。

  • true:只读缓存:**会给所有调用者返回缓存对象的相同实例。**因此这些对象不能被修改, 这提供了很重要的性能优势。
  • false读写缓存: 通过序列化返回缓存对象的拷贝,这种方式会慢一些,但是安全,因此默认是 false。

配置结果

<cache eviction="FIFO" flushInterval="6000" size="512" readOnly="true"/>   

3.Mybatis缓存查询顺序

  • 先查询二级缓存,因为二级缓存中可能会有其他程序查询出来的数据,可以直接拿来使用
  • 如果二级缓存未命中,再查询一级缓存
  • 如果一级缓存也没有命中,则查询数据库
  • SqlSession关闭之后,一级缓存的数据会写入二级缓存
    在这里插入图片描述

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

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

相关文章

springboot襄阳华侨城奇幻度假区服务平台-计算机毕业设计源码93560

目 录 摘要 1 绪论 1.1 研究背景 1.2 研究意义 1.3 开发技术 1.3.1 B/S架构 1.3.2 Spring Boot框架 1.3.3 Java语言 1.3.4 MySQL数据库 1.4论文章节安排 2系统分析 2.1 可行性分析 2.2 系统流程分析 2.2.1 登录流程 2.2.2数据删除流程 2.3 系统…

2024年好用不踩雷的8款图纸加密软件推荐!CAD图纸加密软件!

在2024年&#xff0c;随着信息安全需求的提升&#xff0c;特别是对于设计、建筑、制造等行业的CAD图纸保护&#xff0c;图纸加密软件的选择尤为重要。以下推荐了8款优质的CAD图纸加密软件&#xff0c;这些软件不仅提供了强大的加密功能&#xff0c;还在易用性和兼容性方面表现出…

创新业态下金融头部机构在 FICC 平台建设上的思考与实践

近年来&#xff0c;FICC 投资交易呈现活跃多元态势&#xff0c;创新转型稳步推进。FICC 平台电子化方兴未艾&#xff0c;是机构提升服务效率和质量的一大着力点。因此&#xff0c;在 FICC 平台建设上&#xff0c;许多机构都进行了深入研究&#xff0c;积累了丰富的实践经验。 …

MongoDB快速入门

MongoDB 概念 什么是 MongoDB MongoDB 是在2007年由DoubleClick公司的几位核心成员开发出的一款分布式文档数据库&#xff0c;由C语言编写。 目的是为了解决数据大量增长的时候系统的可扩展性和敏捷性。MongoDB要比传统的关系型数据库简单很多。 在MongoDB中数据主要的组织…

Spring boot 配置文件的加载顺序

Spring Boot 在启动时会扫描以下位置的 application.properties 或者 application.yml 文件作为全局配置文件&#xff1a; –file:./config/–file:./–classpath:/config/–classpath:/以下是按照优先级从高到低的顺序&#xff0c;如下所示&#xff1a; Spring Boot 会全部扫…

医院信息化与智能化系统(10)

医院信息化与智能化系统(10) 这里只描述对应过程&#xff0c;和可能遇到的问题及解决办法以及对应的参考链接&#xff0c;并不会直接每一步详细配置 如果你想通过文字描述或代码画流程图&#xff0c;可以试试PlantUML&#xff0c;告诉GPT你的文件结构&#xff0c;让他给你对应…

自由学习记录(15)

Java注解 else if的省略问题&#xff08;可能看花&#xff09; else if也是取最近的if连通&#xff0c;看上去加了{}就可以正常执行了&#xff0c;缩进要命&#xff0c;不提示真容易看错&#xff0c; 组合数公式和数组参数 在 C 中&#xff0c;数组作为函数参数时&#xff0c;…

【课件分享】蓝光光盘及光驱团标解读

关注我们 - 数字罗塞塔计划 - 10月26日&#xff0c;非常感谢陶光毅老师携特邀嘉宾许斌老师和游泳总能够在百忙之中抽空莅临数字罗塞塔计划直播间&#xff0c;为大家带来蓝光光盘及光驱团标解读。作为标准的起草者&#xff0c;你们的专业见解和宝贵经验&#xff0c;让我们对T/CE…

Lucas带你手撕机器学习——SVM支持向量机

#1024程序员节&#xff5c;征文# 支持向量机&#xff08;SVM&#xff09;的详细讲解 什么是SVM&#xff1f; 支持向量机&#xff08;Support Vector Machine&#xff0c;SVM&#xff09;是一种用于分类和回归的监督学习算法。它的主要任务是从给定的数据中找到一个最佳的决策…

Windows/Linux(服务器)查看显卡的名称

文章目录 1. 使用 nvidia-smi&#xff08;适用于 NVIDIA 显卡&#xff09;2. 使用 wmic 命令&#xff08;Windows&#xff09; 1. 使用 nvidia-smi&#xff08;适用于 NVIDIA 显卡&#xff09; 如果服务器上安装了 NVIDIA 驱动程序&#xff0c;可以使用 nvidia-smi 工具来查看…

vue使用xlsx以及file-saver进行下载xlsx文件以及Unit8Array、ArrayBuffer、charCodeAt的使用

先说Unit8Array、ArrayBuffer、charCodeAt的使用下面会用到这三个 Unit8Array&#xff1a;数组类型表示一个 8 位无符号整型数组&#xff0c;创建时内容被初始化为 0。创建完后&#xff0c;可以以对象的方式或使用数组下标索引的方式引用数组中的元素。 new Uint8Array(); //…

Docker中如何控制服务启动顺序实现探讨

文章目录 一、Docker概述二、Docker三剑客1. Compose2. Machine3. Swarm 三、简要需求1. 样例工程2. 代码模块3. 调用方向4. 期望启动顺序 四、思路分析1.各走各路1.&#xff09;docker-compose -f指定不同配置文件2.&#xff09;docker-compose up -d service-name指定服务名3…

【CSS in Depth 2 精译_055】8.3 伪类 :is() 和 :where() 的正确打开方式

当前内容所在位置&#xff08;可进入专栏查看其他译好的章节内容&#xff09; 【第三部分 现代 CSS 代码组织】 ✔️【第八章 层叠图层及其嵌套】 ✔️ 8.1 用 layer 图层来操控层叠规则&#xff08;上篇&#xff09; 8.1.1 图层的定义&#xff08;上篇&#xff09;8.1.2 图层的…

巡飞单机多旋翼无人机技术详解

巡飞单机多旋翼无人机技术是一种集成了多种先进技术的无人机系统&#xff0c;它具备自主飞行、长续航、高精度控制以及多任务负载能力等特点。以下是对巡飞单机多旋翼无人机技术的详细解析&#xff1a; 一、机架与结构设计 1.材料选择&#xff1a;为了确保无人机能够承载足够…

cmake命令使用

有关cmake的入门简介可参见 CMake入门教程_cmake静态test.c编译-CSDN博客 本文是进一步对cmake常用命令做进一步详述 配置项目 cmake_minimum_required 作用 配置cmake最低版本 用法 cmake_minimum_required(VERSION 3.0) project 作用&#xff1a;设置预设变量 PROJEC…

深度学习(一)基础:神经网络、训练过程与激活函数(1/10)

深度学习基础&#xff1a;神经网络、训练过程与激活函数 引言&#xff1a; 深度学习作为机器学习的一个子领域&#xff0c;近年来在人工智能的发展中扮演了举足轻重的角色。它通过模仿人脑的神经网络结构&#xff0c;使得计算机能够从数据中学习复杂的模式和特征&#xff0c;…

dmsql日志分析工具部署与使用DM8/DM7

dmsql日志分析工具部署与使用DM8/DM7 1 环境介绍2 JAVA 环境变量配置2.1 Os Kylin 10 JAVA 环境变量配置2.2 Windos7 JAVA环境变量配置 3 数据库配置3.1 数据库初始化参数3.2 数据库创建表 4 配置DMLOG日志分析工具4.1 Kylin v10 配置DMLOG日志分析工具4.2 执行日志分析4.3 Win…

linux面试题复习

前言 现在只是初版&#xff0c;很多格式我还没有改好&#xff0c;会慢慢修改订正。 可能用到的网址&#xff1a;在线 EXCEL 到 MARKDOWN 转换器。 参考了很多网上的面试题和外网上的面试题&#xff1a; 参考文档&#xff1a; 程序员的50大Linux面试问题及答案 Top 60 Linux …

MySQL——test4(综合练习)

目录 建库建表&#xff08;题目&#xff09;处理表1. 修改student 表中年龄(sage)字段属性&#xff0c;数据类型由int 改变为smallint2. 为Course表中Cno 课程号字段设置索引,并查看索引3. 为SC表建立按学号(sno)和课程号(cno)组合的升序的主键索引&#xff0c;索引名为SC_INDE…

数据结构:“小猫钓鱼游戏”

一&#xff1a;题目 栈和队列的综合应用&#xff1a;“小猫钓鱼”的游戏规则是&#xff1a;将一副扑克牌平均分成两份&#xff0c;每人拿一份。玩家甲先拿出手中的第一张扑克牌放在桌上&#xff0c;然后玩家乙也拿出手中的第一张扑克牌&#xff0c;并放在玩家甲刚打出的扑克牌的…