【MyBatis】第八篇:一级,二级缓存
其实缓存字面的意思就是将一些内容缓存下来,等下次使用的时候可以直接调用,通过数据库得到数据,有时候会使用相同的数据,所以mybatis自然也支持缓存。
而mybatis按照缓存的效果可以分两大类:一级缓存和二级缓存。
一级缓存
其实一级缓存是SqlSession级别,通过SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库中重写访问。
还是老规矩进行代码演示:
List<Student> getStudent();
<select id="getStudent" resultType="Student">SELECT sid , sname , sage , ssex , gid FROM testmybatis.student</select>
然后调用的时候,不关闭SqlSession,然后连续调用getStudent() :
System.out.println(" -------------------- 第一次 " + studentMapper.getStudent());System.out.println(" -------------------- 第二次 " + studentMapper.getStudent());

可以看出sql语句,只是调用了一次,但是还是得到了数据。
但是一级缓存也是会失效的,其中有四种情况:
-
不同的SqlSession对应不同一级缓存,比如例子一直说用的同一个sqlsession,也没有关闭sqlsession重写创建了一个。
-
同一个SqlSession,但是两次查询的条件不同,甚至是操作相同,但是方法名不同,也不会调用缓存,可以看下演示:
List<Student> getStudent();List<Student> getStudent1();<select id="getStudent" resultType="Student">SELECT sid , sname , sage , ssex , gid FROM testmybatis.student</select><select id="getStudent1" resultType="Student">SELECT sid , sname , sage , ssex , gid FROM testmybatis.student</select>然后调用:
System.out.println(" -------------------- 第一次 " + studentMapper.getStudent());System.out.println(" -------------------- 第二次 " + studentMapper.getStudent());System.out.println(" -------------------- 另一个第一次 " + studentMapper.getStudent1());System.out.println(" -------------------- 第三次 " + studentMapper.getStudent());

可以看出哪怕同一个sqlsession其一样的sql语句,通过两个不同方法也不会调用缓存,因为sql语句执行了两次。当然其也不会影响已缓存是数据。
-
同一个sqlsession同一个查询,在两者依次执行期间,执行了任何依次增改操作。
来实体体验一把:
List<Student> getStudent();void deleteStudent();<select id="getStudent" resultType="Student">SELECT sid , sname , sage , ssex , gid FROM testmybatis.student</select><delete id="deleteStudent"><!--这里删除一个不存在的数据 -->delete from testmybatis.student where sid='100'</delete>System.out.println(" -------------------- 第一次 " + studentMapper.getStudent());studentMapper.deleteStudent();System.out.println(" -------------------- 第二次 " + studentMapper.getStudent());

可以看出其删除无论是否存在
-
同一个SqlSession两次执行同一个查询中介,执行了手动清楚缓存。
System.out.println(" -------------------- 第一次 " + studentMapper.getStudent()); // 调用clearCache() 手动清楚了缓存sqlSession.clearCache();System.out.println(" -------------------- 第二次 " + studentMapper.getStudent());

二级缓存
二级缓存是SqlSessionFactory级别的,同一个SqlSessionFactory创建的SqlSession查询的结果会被缓存,此后执行相同的查询语句,数据就会从缓存中得到。
启用的条件:
- 在核心配置文件中,加入配置:
<setting name="cacheEnabled"value="true" /> - 在映射文件中加入
<cache /> - 查询的数据转换的实体类类型,必须实现序列化接口
Serializable。 - SqlSession在关闭或者提交以后二级缓存才会有效。
还是老规矩进行演示:
前提在核心配置文件mybatis-config.xml中配置
<settings><setting name="cacheEnabled" value="true" /></settings>
然后再映射文件中添加:
<cache></cache>
实体类需要实现序列化接口:
public class Student implements Serializable
现在开始演示:
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 这个通过代理模式,传入什么类返回什么类StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);System.err.println(" -------------------- 第一次 sqlSession -- getStudent " + studentMapper.getStudent());// 不关闭的话,sqlSession.close();SqlSession sqlSession1 = sqlSessionFactory.openSession();StudentMapper studentMapper1 = sqlSession1.getMapper(StudentMapper.class);System.err.println(" -------------------- 第一次 sqlSession1 -- 方法名为 getStudent " + studentMapper1.getStudent());System.err.println(" -------------------- 第一次 sqlSession1 -- 方法名为 getStudent1 " + studentMapper1.getStudent1());studentMapper1.deleteStudent();System.err.println(" -------------------- 第二次 sqlSession1 -- 执行deleteStudent后调用 getStudent " + studentMapper1.getStudent());sqlSession1.close();

可以看出了只要删除或者修改了数据库,无论是一级缓存还是二级缓存都会同时失效。
这个又有一个疑问了,那就是一级缓存和二级缓存的查询顺序是什么?
先查询二级缓存,没有再查询二级缓存,如果还没有再查询数据库。
为什么会这样,因为二级缓存覆盖的更广,一级缓存中没有但是在二级缓存中,减少去数据库中取数的频次。
补充--------二级缓存的配置
其实再映射文件中可以配置一些属性:
看一下官网举出的例子:
<cacheeviction="FIFO"flushInterval="60000"size="512"readOnly="true"/>
eviction 属性是缓存回收策略,默认是LRU。
这个更高级的配置创建了一个 FIFO 缓存,每隔 60 秒刷新,最多可以存储结果对象或列表的 512 个引用,而且返回的对象被认为是只读的,因此对它们进行修改可能会在不同线程中的调用者产生冲突。
可用的清除策略有:
LRU– 最近最少使用:移除最长时间不被使用的对象。FIFO– 先进先出:按对象进入缓存的顺序来移除它们。SOFT– 软引用:基于垃圾回收器状态和软引用规则移除对象。WEAK– 弱引用:更积极地基于垃圾收集器状态和弱引用规则移除对象。
默认的清除策略是 LRU。
flushInterval(刷新间隔)属性可以被设置为任意的正整数,设置的值应该是一个以毫秒为单位的合理时间量。 默认情况是不设置,也就是没有刷新间隔,缓存仅仅会在调用语句时刷新。
size(引用数目)属性可以被设置为任意正整数,要注意欲缓存对象的大小和运行环境中可用的内存资源。默认值是 1024。
readOnly(只读)属性可以被设置为 true 或 false。只读的缓存会给所有调用者返回缓存对象的相同实例。 因此这些对象不能被修改。这就提供了可观的性能提升。而可读写的缓存会(通过序列化)返回缓存对象的拷贝。 速度上会慢一些,但是更安全,因此默认值是 false。
当然还有一个属性没有写,那就是type:其在使用第三方的缓存的时候使用,因为有些第三方的缓存的功能会更强大,所以有时候会使用第三方缓存,这个就下一篇具体聊。
相关文章:
【MyBatis】第八篇:一级,二级缓存
其实缓存字面的意思就是将一些内容缓存下来,等下次使用的时候可以直接调用,通过数据库得到数据,有时候会使用相同的数据,所以mybatis自然也支持缓存。 而mybatis按照缓存的效果可以分两大类:一级缓存和二级缓存。 一…...
【大唐杯备考】——5G基站开通与调测(学习笔记)
📖 前言:本期介绍5G基站开通与调测。 目录🕒 1. 概述🕒 2. 5G基站开通与调测基础🕘 2.1 3.5GHz单模100MHz配置(S111)🕘 2.2 3.5GHz单模100MHz配置(S111111)&a…...
redhat7 忘记root密码,重置办法
来自https://www.tracymc.cn/archives/802 亲测可用,太感谢了,在此记录一下,原文有图 1.启动的时候,在有启动项界面,相应启动项内核名称上按“e”; 2.进入后,找到linux16开头的地方,按“end”键或者controle到最后,输入rd.break,再按ctrlx进…...
QML- 对象属性
QML- 对象属性一、概述二、id 属性三、Property 属性1. 定义属性1. 自定义属性定义中的有效类型2. 为属性属性赋值1. 初始化时的值赋值2. 命令式赋值3. 静态值和绑定表达式值4. 类型安全5. 特殊属性类型1. 对象列表属性2. 分组属性6. 属性别名1. 属性别名的注意事项2. 属性别名…...
将.js文件转成vue标签结构的样式
例如:下图所示: 依次识别获取.js文件中的tag和props,可以理解为字符串拼接,将整个vue的标签结构看作是一个字符串。 话不多说,先放上完整代码,思路看代码备注。(自己实现的时候,可以…...
前端知识点复盘
组件和jsx <body><div id"root"></div><script type"text/babel">const root ReactDOM.createRoot(document.getElementById("root"))class App extends React.Component {render() {return (<div> <h1>s…...
前端JavaScript获取图片文件的真实格式
常见方式判断图片格式 当我们进行前端开发,需要处理图片上传功能,针对图片格式做判断时,常规的方法都是使用文件后缀名来判断,如下代码所示: input.addEventListener(change, (e) > {const file e.target.files[…...
今天面了一个来华为要求月薪25K,明显感觉他背了很多面试题...
最近有朋友去华为面试,面试前后进行了20天左右,包含4轮电话面试、1轮笔试、1轮主管视频面试、1轮hr视频面试。 据他所说,80%的人都会栽在第一轮面试,要不是他面试前做足准备,估计都坚持不完后面几轮面试。 其实&…...
11 Advanced CNN
文章目录GoogLeNetInception Module1x1 Conv计算效果代码实现总结ResNet (残差网络)问题引入梯度消失与传统神经网络的比较代码实现课程来源: 链接对于前篇中所提到问题,设计出的是一种类似于LeNet5的线性结构,而对于大多数问题,简…...
亿级高并发电商项目---万达商城项目搭建(二)
👏作者简介:大家好,我是小童,Java开发工程师,CSDN博客博主,Java领域新星创作者 📕系列专栏:前端、Java、Java中间件大全、微信小程序、微信支付、若依框架、Spring全家桶 Ǵ…...
UML术语标准和分类
一、UML术语标准 1.中文UML术语标准 中国软件行业协会(CSIA)与日本UML建模推进协会(UMTP)共同在中国推动的UML专家认证,两个协会共同颁发认证证书、两国互认,CSIA与UMTP共同推出了UML中文术语…...
LeetCode 刷题系列 -- 151. 反转字符串中的单词
给你一个字符串 s ,请你反转字符串中 单词 的顺序。单词 是由非空格字符组成的字符串。s 中使用至少一个空格将字符串中的 单词 分隔开。返回 单词 顺序颠倒且 单词 之间用单个空格连接的结果字符串。注意:输入字符串 s中可能会存在前导空格、尾随空格或…...
二十二、Gtk4-ListView
GTK 4添加了新的列表对象GtkListView、GtkGridView和GtkColumnView。这个新特性在Gtk API参考—列表小构件概述中有描述。 GTK 4还有其他实现列表的方法。它们是GtkListBox和GtkTreeView,它们是从GTK 3接管的。在Gtk开发博客中有一篇关于Matthias Clasen所写的列表…...
ASP.NET Core3.1实战教程---基于Jquery单文件上传
这个必须记录一下费劲啊!废了我2天的时间,昔日的net快速已经没落....就文件上传都这么费劲。 先说下要求(在线apk文件上传实现手机端整包更新): 1、为了简化需求文件上传和数据提交分开执行 2、选完文件后按钮变成上…...
10 卷积神经网络CNN(基础篇)
文章目录全连接CNN过程卷积过程下采样过程全连接层卷积原理单通道卷积多通道卷积改进多通道总结以及课程代码卷积改进PaddingStride下采样过程大池化层(Max Pooling)简单卷积神经网络的实现课程代码本篇课程来源: 链接部分文本来源参考&#…...
Windows下LuaBridge2.8的环境配置及简单应用
Windows下LuaBridge2.8的环境配置及简单应用 LuaBridge2.8下载链接: https://github.com/vinniefalco/LuaBridge/tags 关于Lua的环境配置可参考以下链接(这里不做简述): https://ufgnix0802.blog.csdn.net/article/details/125341…...
每天10个前端小知识 【Day 10】
前端面试基础知识题 1. es5 中的类和es6中的class有什么区别? 在es5中主要是通过构造函数方式和原型方式来定义一个类,在es6中我们可以通过class来定义类。 class类必须new调用,不能直接执行。 class类执行的话会报错,而es5中…...
【LeetCode】1223. 掷骰子模拟
1223. 掷骰子模拟 题目描述 有一个骰子模拟器会每次投掷的时候生成一个 1 到 6 的随机数。 不过我们在使用它时有个约束,就是使得投掷骰子时,连续 掷出数字 i 的次数不能超过 rollMax[i](i 从 1 开始编号)。 现在,…...
SPSS数据分析软件的安装与介绍(附网盘链接)
🤵♂️ 个人主页:艾派森的个人主页 ✍🏻作者简介:Python学习者 🐋 希望大家多多支持,我们一起进步!😄 如果文章对你有帮助的话, 欢迎评论 💬点赞Ǵ…...
2022年38女神节大促美妆、珠宝、母婴、保健电商数据回顾
近期,我们陆续接收到了品牌商家朋友们对于2022年女神节大促期间部分品类的数据需求,希望能对今年的大促活动有一个更宏观的认知、更精准的预测,从而拿到更好的数据效果。 为此,在距离大促开启一个月的备货阶段,鲸参谋决…...
龙虎榜——20250610
上证指数放量收阴线,个股多数下跌,盘中受消息影响大幅波动。 深证指数放量收阴线形成顶分型,指数短线有调整的需求,大概需要一两天。 2025年6月10日龙虎榜行业方向分析 1. 金融科技 代表标的:御银股份、雄帝科技 驱动…...
Docker 离线安装指南
参考文章 1、确认操作系统类型及内核版本 Docker依赖于Linux内核的一些特性,不同版本的Docker对内核版本有不同要求。例如,Docker 17.06及之后的版本通常需要Linux内核3.10及以上版本,Docker17.09及更高版本对应Linux内核4.9.x及更高版本。…...
【决胜公务员考试】求职OMG——见面课测验1
2025最新版!!!6.8截至答题,大家注意呀! 博主码字不易点个关注吧,祝期末顺利~~ 1.单选题(2分) 下列说法错误的是:( B ) A.选调生属于公务员系统 B.公务员属于事业编 C.选调生有基层锻炼的要求 D…...
C# SqlSugar:依赖注入与仓储模式实践
C# SqlSugar:依赖注入与仓储模式实践 在 C# 的应用开发中,数据库操作是必不可少的环节。为了让数据访问层更加简洁、高效且易于维护,许多开发者会选择成熟的 ORM(对象关系映射)框架,SqlSugar 就是其中备受…...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
ArcPy扩展模块的使用(3)
管理工程项目 arcpy.mp模块允许用户管理布局、地图、报表、文件夹连接、视图等工程项目。例如,可以更新、修复或替换图层数据源,修改图层的符号系统,甚至自动在线执行共享要托管在组织中的工程项。 以下代码展示了如何更新图层的数据源&…...
41道Django高频题整理(附答案背诵版)
解释一下 Django 和 Tornado 的关系? Django和Tornado都是Python的web框架,但它们的设计哲学和应用场景有所不同。 Django是一个高级的Python Web框架,鼓励快速开发和干净、实用的设计。它遵循MVC设计,并强调代码复用。Django有…...
实现p2p的webrtc-srs版本
1. 基本知识 1.1 webrtc 一、WebRTC的本质:实时通信的“网络协议栈”类比 将WebRTC类比为Linux网络协议栈极具洞察力,二者在架构设计和功能定位上高度相似: 分层协议栈架构 Linux网络协议栈:从底层物理层到应用层(如…...
Android Settings 数据库生成、监听与默认值配置
一、Settings 数据库生成机制 传统数据库生成(Android 6.0 前) 路径:/data/data/com.android.providers.settings/databases/settings.db创建流程: SQL 脚本初始化:通过 sqlite 工具创建数据库文件…...
Linux知识回顾总结----进程状态
本章将会介绍进程的一些概念:冯诺伊曼体系结构、进程是什么,怎么用、怎么表现得、进程空间地址、物理地址、虚拟地址、为什么存在进程空间地址、如何感性得去理解进程空间地址、环境变量是如何使用的。 目录 1. 冯诺伊曼体系结构 1.1 是什么 1.2 结论 …...
