Mybatis缓存测试

实体类

Student

@Data
@Table(name = "student")
public class StudentEntity implements Serializable {private static final long serialVersionUID = 1L;@Id@Column(name = "id")private Long id;@Column(name = "name")private String name;@Column(name = "class_id")private Long classId;@Transientprivate String className;}

Class

@Data
@Table(name = "class")
public class ClassEntity implements Serializable {private static final long serialVersionUID = 1L;@Id@Column(name = "id")private Long id;@Column(name = "name")private String name;}

表结构

CREATE TABLE `student` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,`class_id` int(11) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8;
CREATE TABLE `class` (`id` int(11) NOT NULL AUTO_INCREMENT,`name` varchar(255) DEFAULT NULL,PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;

一级缓存

一级缓存是sqlSession级别的,二级缓存是SqlSessionFactory级别的

一级缓存-测试1

   @Autowiredprivate SqlSessionFactory sqlSessionFactory;@Testpublic void t1() {SqlSession sqlSession = sqlSessionFactory.openSession();// 同一个sqlSession,同一个mapper实例,执行相同的查询语句StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);studentMapper.selectAll();studentMapper.selectAll();// 结论:只会出现1次sql语句,第二次查询走缓存}

在这里插入图片描述

一级缓存-测试2

   @Testpublic void t2() {SqlSession sqlSession = sqlSessionFactory.openSession();// 同一个sqlSession,不同的mapper实例,执行相同的查询语句StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);studentMapper.selectAll();StudentMapper studentMapper2 = sqlSession.getMapper(StudentMapper.class);studentMapper2.selectAll();// 结论:只会出现1次sql语句,第二次查询走缓存}

在这里插入图片描述

一级缓存-测试3

   @Testpublic void t3() {// 不同sqlSession,执行相同的查询语句SqlSession sqlSession = sqlSessionFactory.openSession();SqlSession sqlSession2 = sqlSessionFactory.openSession();StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);studentMapper.selectAll();StudentMapper studentMapper2 = sqlSession2.getMapper(StudentMapper.class);studentMapper2.selectAll();// 结论:出现2次sql语句,没有缓存效果}

在这里插入图片描述

一级缓存-测试4(update)

   @Testpublic void t4() {SqlSession sqlSession = sqlSessionFactory.openSession();// 第一次查询StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);List<StudentEntity> list = studentMapper.selectAll();// 更新操作StudentEntity student = list.get(0);student.setName("修改学生姓名");studentMapper.updateByPrimaryKey(student);// 第二次查询studentMapper.selectAll();// 结论:第一次会出现sql语句,由于进行了更新操作,导致缓存失效,第二次查询也会重新查询sql}

在这里插入图片描述

一级缓存-测试5(update)

和测试4类似,但是update的对象改为class,看看是否会影响student的查询

   @Testpublic void t5() {SqlSession sqlSession = sqlSessionFactory.openSession();// 第一次查询studentStudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);List<StudentEntity> list = studentMapper.selectAll();// 更新classClassMapper classMapper = sqlSession.getMapper(ClassMapper.class);ClassEntity classx = classMapper.selectAll().get(0);classx.setName("修改班级姓名");classMapper.updateByPrimaryKey(classx);// 第二次查询studentstudentMapper.selectAll();// 结论:第一次会出现sql语句,由于进行了更新操作(即使不是同一个mapper实例),也会导致缓存失效,第二次查询也会重新查询sql}

在这里插入图片描述

一级缓存-测试6(springboot失效)

   @Autowiredprivate StudentMapper studentMapper;@Testpublic void t6() {// 使用mybatis整合springboot后,直接查询2次studentMapper.selectAll();studentMapper.selectAll();// 结论:会出现2次sql查询,缓存失效,因为每一次sql语句的执行都是使用新的sqlSession}

在这里插入图片描述

二级缓存

一级缓存默认开启,二级缓存默认关闭

开启配置

mybatis:configuration:cache-enabled: true

给mapper添加<cache/>,前面用的通用mapper的selectAll方法,二级缓存一直没生效,这里重新手写一个查询方法getAll,再加上useCache配置才行

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.tw.nr.network.dao.mapper.StudentMapper"><cache/><!--开启二级缓存--><!--获取学生列表--><select id="getAll" resultType="com.tw.nr.network.entity.StudentEntity" useCache="true">select * from student;</select><!--获取学生详细信息--><select id="getStudentDetail" resultType="com.tw.nr.network.entity.StudentEntity" useCache="true">SELECTa.`name`,b.`name` AS classNameFROMstudent aJOIN class b ON a.class_id = b.idwherea.id=#{id}</select></mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.tw.nr.network.dao.mapper.ClassMapper"><cache/><!--开启二级缓存--></mapper>

二级缓存-测试1

   @Testpublic void t7() {// 不同sqlSession,执行相同的查询语句SqlSession sqlSession = sqlSessionFactory.openSession();SqlSession sqlSession2 = sqlSessionFactory.openSession();StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);studentMapper.getAll();sqlSession.commit();StudentMapper studentMapper2 = sqlSession2.getMapper(StudentMapper.class);studentMapper2.getAll();// 结论:只会查询1次sql语句,第二次查询走缓存}

在这里插入图片描述

二级缓存-测试2(脏数据)

二级缓存不适合多表查询,因为studentclass处于不同的命名空间,在student的命名空间执行了sqlA的联表查询(student和class联表),进行了缓存,然后class执行了更新,但这并不会刷新sqlA的缓存,导致sqlA还是读取到了脏数据

   @Testpublic void t8() {SqlSession sqlSession = sqlSessionFactory.openSession();// 第一次查询学生的详细信息(联查了class表)StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);StudentEntity student = studentMapper.getStudentDetail(1L);System.out.println(student);sqlSession.commit();// 更新了class表ClassMapper classMapper = sqlSession.getMapper(ClassMapper.class);ClassEntity classx = classMapper.selectAll().get(0);classx.setName("班级1000");classMapper.updateByPrimaryKey(classx);sqlSession.commit();// 再次查询学生的详细信息student = studentMapper.getStudentDetail(1L);System.out.println(student);/*** 结论:读取到了脏数据,二级缓存不适合多表查询,因为student和class处于不同的命名空间,在student的命名空间执行了sqlA的联表查询(student和class联表),进行了缓存* 然后class执行了更新,但这并不会刷新sqlA的缓存,导致sqlA还是读取到了脏数据* */}

在这里插入图片描述

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

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

相关文章

3D模型在电商行业的应用有哪些?

3D模型在电商行业的应用广泛且多样化&#xff0c;以下是几个主要的应用领域&#xff1a; 1、商品展示&#xff1a; 3D立体展示技术能够利用商品的3D模型进行全方位的展示&#xff0c;支持720旋转和任意缩放&#xff0c;使得消费者能够更直观地了解产品的外观、结构和特点。这…

中学理化生实验室建设及配置要求

在中学物理、化学、生物等学科教学中&#xff0c;实验占据了非常重要的地位&#xff0c;是整个教学过程中不可或缺的部分。很多理科教学需要在实验室完成演示和学习任务&#xff0c;实验室也是保证教学计划得以实施的物质基础。因此&#xff0c;中学理化生实验室建设标准与否&a…

React+TS前台项目实战(十四)-- 响应式头部导航+切换语言相关组件封装

文章目录 前言Header头部相关组件1. 功能分析2. 相关组件代码详细注释3. 使用方式4. Gif图效果展示 总结 前言 在这篇博客中&#xff0c;我们将封装一个头部组件&#xff0c;根据不同设备类型来显示不同的导航菜单&#xff0c;会继续使用 React hooks 和styled-components库来…

IIS代理配置-反向代理

前后端分离项目&#xff0c;前端在开发中使用proxy代理解决跨域问题&#xff0c;打包之后无效。 未配置前无法访问 部署环境为windows IIS&#xff0c;要在iis设置反向代理 安装代理模块 需要在iis中实现代理&#xff0c;需要安装Application Request Routing Cache和URL重…

49.Chome浏览器有三种清缓存方式

49.Chome浏览器有三种清缓存方式&#xff1a;正常重新加载、硬件重新加载、清空缓存并硬性重新加载 1、【正常重新加载】 触发方式&#xff1a;①F5  ②CtrlR  ③在地址栏上回车  ④点击链接 如果缓存不过期会使用缓存。这样浏览器可以避免重新下载JavaScript文件、图像、…

创新实训2024.05.01日志:document-loaders

在建立易学知识库的过程中&#xff0c;仅仅有向量数据库以及词嵌入模型、分词器是不够的&#xff0c;因为我们有大量的非结构化文本&#xff08;如doc,pdf&#xff09;或者是图片需要上传&#xff08;例如pdf里面有图片&#xff09;&#xff0c;此时词嵌入无法直接向向量数据库…

自学鸿蒙HarmonyOS的ArkTS语言<三>路由跳转及传参

【官方文档传送门】 一、导入模块 import router from ohos.router二、新增页面配置 三、常用api 1、跳转到应用内的指定页面 build() {Row() {Button(下一页).onClick(() > {router.pushUrl({url: pages/Index2,params: {name: test}})})}.height(100%)}2、用应用内的某…

SpringBoot配置第三方专业缓存技术jetcache方法缓存方案

jetcache方法缓存 我们可以给每个方法配置缓存方案 JetCache 是一个基于 Java 的缓存库&#xff0c;支持多种缓存方案和缓存策略&#xff0c;主要用于提升应用程序的性能和响应速度。它提供了多种缓存模式和特性&#xff0c;可以根据需求选择合适的缓存方案。 JetCache 的主…

在WordPress上添加亚马逊联盟链接的三种方法

在互联网快速发展的今天&#xff0c;很多人都希望通过网络来增加收入&#xff0c;而加入亚马逊联盟计划&#xff08;Amazon Associates&#xff09;无疑是一个不错的选择。如果你有一个WordPress网站&#xff0c;那么在文章中添加亚马逊联盟链接是个很好的变现方式。今天&#…

钡铼BL110在智慧气象站实现Modbus转MQTT无线接入主流云

随着物联网&#xff08;IoT&#xff09;技术的发展&#xff0c;各行各业都在积极探索将智能设备与云平台相结合&#xff0c;以提升系统的智能化和自动化水平。智慧气象站作为其中重要的一环&#xff0c;通过实时监测环境数据&#xff0c;为农业、交通、航空等行业提供精准的气象…

Idea Git中 unversioned files的处理

项目中&#xff0c;使用git commit命令可以查看当前所在的分支&#xff0c;以及当前改动的文件&#xff0c;可以使用快捷键Alt 0打开/关闭&#xff1b;如下图所示&#xff0c; 可以看到分成了两个不同的区域&#xff0c; Changes 表示有改动的文件&#xff0c;包括修改、新增…

apache activeMq

https://blog.csdn.net/qq_29651203/article/details/108487924 游览器输入地址: http://127.0.0.1:8161/admin/ 访问activemq管理台 账号和密码默认为: admin/admin# yml配置的密码也是如下的密码 activemq:url: failover:(tcp://localhost:61616)username: adminpassword: ad…

哪个充电宝牌子好?性价比高与质量好并存!热门充电宝推荐!

随着科技的不断进步&#xff0c;我们的日常生活越来越依赖于便携式电子设备。然而&#xff0c;电池续航问题始终是这些设备的一大软肋。为了确保我们的智能手机、平板电脑、甚至是智能手表在忙碌的日子里始终有电&#xff0c;一个可靠的充电宝成为了我们的必备之选。面对市场上…

VoIP Hopper一键分析VoIP 网络信息(KALI工具系列二十九)

目录 1、KALI LINUX 简介 2、VoIP Hopper工具简介 3、信息收集 3.1 目标主机IP 3.2kali的IP 4、操作实例 4.1 VLAN 跳跃攻击 4.2 指定MAC地址 4.3 设置参数 5、总结 1、KALI LINUX 简介 Kali Linux 是一个功能强大、多才多艺的 Linux 发行版 &#xff0c;广泛用于网络…

flask实战之模板实现公共导航

基础实现 目标 在Flask中&#xff0c;使用模板继承和块&#xff08;blocks&#xff09;可以方便地提取公共导航菜单&#xff0c;使得您可以在多个页面上重用相同的导航结构。以下是一个基本示例&#xff0c;展示如何创建一个包含公共导航菜单的模板&#xff1a; 创建基础模板…

前端菜鸡学习日记 -- 关于pnpm

哈咯哇大家&#xff0c;我又来了&#xff0c;最近稍微悠闲一些&#xff0c;所以就趁着这个机会学习一些新的知识&#xff0c;今天就是碰巧遇到了pnm&#xff0c;这个可以看作是npm的升级版本&#xff0c;比npm要快&#xff0c;用起来也更得劲更迅速 官网地址&#xff1a;https…

【CT】LeetCode手撕—103. 二叉树的锯齿形层序遍历

目录 题目1- 思路2- 实现⭐103. 二叉树的锯齿形层序遍历——题解思路 2- ACM实现 题目 原题连接&#xff1a;103. 二叉树的锯齿形层序遍历 1- 思路 二叉树的层序遍历&#xff0c;遇到奇数时&#xff0c;利用 Collections.reverse() 翻转即可 2- 实现 ⭐103. 二叉树的锯齿形层…

优惠卷秒杀(并发问题)

Redis实战篇 | Kyles Blog (cyborg2077.github.io) 目录 一、Redis实现全局唯一id 二、添加优惠卷 三、实现秒杀下单 四、解决超卖问题&#xff08;库存为负&#xff09; 乐观锁解决超卖问题&#xff08;CAS法&#xff09; 五、实现一人一单 ​编辑 悲观锁解决一人一单问题…

QT绘画仪表盘

代码一步一步讲&#xff0c;就不写用啥之类的了&#xff0c;暗部走来&#xff0c;自己找使用的类以及使用方法 1、创建工程 2、重载paintEvent #include <QMainWindow> #include <QPainter> #include <QPaintEvent> protected:virtual void paintEvent(QP…

QT自定义标题栏窗口其一:实现拖动及可拉伸效果

1、效果 2、核心代码 #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(paren