MyBatis的缓存!!!!
-
为什么使用缓存?
首次访问时,查询数据库,并将数据存储到内存中;再次访问时直接访问缓存,减少IO、硬盘读写次数、提高效率
-
Mybatis中的一级缓存和二级缓存?
-
一级缓存:
它指的是mybatis中的SqlSession对象的缓存。当我们执行完查询之后,查询的结果会同时存在在SqlSession为我们提供的一块区域中。当我们再次查询同样的数据,mybatis会先去SqlSession中查询是否有,有的话直接拿出来使用。当SqlSession对象消失时,Mybatis的一级缓存也就消失了。
-

-
二级缓存:
它指的是Mybatis中SqlSessionFactory对象的缓存,由同一个SqlSessioFactory对象创建的SqlSession共享其缓存。
-

-
1.一级缓存(默认开启)
(1) 首先在UserMapper接口定义两个方法:
package com.by.mapper;import com.by.pojo.User;
import org.apache.ibatis.annotations.Param;
import org.junit.Test;import java.util.List;/*** <p>Project: mybatis - UserMapper</p>* <p>Powered by scl On 2023-12-22 15:52:05</p>* <p>描述:<p>** @author 孙臣龙 [1846080280@qq.com]* @version 1.0* @since 17*/
public interface UserMapper {User getUserById(Integer id);void deleteUserById(Integer id);
}
(2)在UserMapper.xml文件中实现这两个方法:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.by.mapper.UserMapper"><select id="getUserById" parameterType="int" resultType="user">select *from userwhere id = #{id}</select><delete id="deleteUserById" parameterType="int">deletefrom userwhere id = #{id};</delete>
</mapper>
(3)测试类:
/** Copyright (c) 2020, 2023, All rights reserved.**/
package com.by;import com.by.mapper.UserMapper;
import com.by.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;/*** <p>Project: mybatis - MyBatisTest</p>* <p>Powered by scl On 2023-12-18 11:44:53</p>* <p>描述:<p>** @author 孙臣龙 [1846080280@qq.com]* @version 1.0* @since 17*/
public class MyBatisTestCache {private InputStream inputStream;private SqlSession sqlSession;@Beforepublic void init() throws IOException {加载配置文件//String resource = "mybatis-config.xml";//inputStream = Resources.getResourceAsStream(resource);//创建sqlSessionFActory//SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//获得数据的绘画实例//sqlSession = sessionFactory.openSession();}/*** 一级缓存** @throws IOException*/@Testpublic void testFirstGoCache() {UserMapper userMapper1 = sqlSession.getMapper(UserMapper.class);UserMapper userMapper2 = sqlSession.getMapper(UserMapper.class);System.out.println("=========One===========");User user1 = userMapper1.getUserById(42); // 执行sql语句System.out.println(user1);System.out.println("=========Two===========");User user2 = userMapper2.getUserById(42); // 不执行sql语句,走缓存System.out.println(user2);}/*** 一级缓存,不走缓存,同一个sqlSession,中间执行了增删改** @throws IOException*/@Testpublic void testFirstNoCache() {UserMapper userMapper1 = sqlSession.getMapper(UserMapper.class);UserMapper userMapper2 = sqlSession.getMapper(UserMapper.class);System.out.println("=========One===========");User user1 = userMapper1.getUserById(42); // 执行sql语句System.out.println(user1);System.out.println("========同一个sqlsession之间执行增删改========");userMapper1.deleteUserById(41);sqlSession.commit();System.out.println("=========Two===========");User user2 = userMapper2.getUserById(42); // 执行sql语句System.out.println(user2);}/*** 一级缓存,不走缓存,不同的sqlSession** @throws IOException*/@Testpublic void testFirstNoCache2() throws IOException {String resource = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);// 创建sqlSessionFActorySqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession1 = sessionFactory.openSession();UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);// 获得数据的绘画实例SqlSession sqlSession2 = sessionFactory.openSession();UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);System.out.println("=========One===========");User user1 = userMapper1.getUserById(42); // 执行sql语句System.out.println(user1);System.out.println("=========Two===========");User user2 = userMapper2.getUserById(42); // 执行sql语句System.out.println(user2);}@Afterpublic void close() throws IOException {//inputStream.close();//sqlSession.close();}}
2.二级缓存(需要手动开启)
(1)在UserMapper接口中创建两个方法:同上
(2)在UserMapper.xml文件中实现这两个方法:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.by.mapper.UserMapper"><!--局部开启二级缓存--><cache></cache><select id="getUserById" parameterType="int" resultType="user">select *from userwhere id = #{id}</select><delete id="deleteUserById" parameterType="int">deletefrom userwhere id = #{id};</delete>
</mapper>
(3)测试类:
/** Copyright (c) 2020, 2023, All rights reserved.**/
package com.by;import com.by.mapper.UserMapper;
import com.by.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;import java.io.IOException;
import java.io.InputStream;/*** <p>Project: mybatis - MyBatisTest</p>* <p>Powered by scl On 2023-12-18 11:44:53</p>* <p>描述:<p>** @author 孙臣龙 [1846080280@qq.com]* @version 1.0* @since 17*/
public class MyBatisTestCache2 {private InputStream inputStream;private SqlSession sqlSession;@Beforepublic void init() throws IOException {加载配置文件//String resource = "mybatis-config.xml";//inputStream = Resources.getResourceAsStream(resource);//创建sqlSessionFActory//SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);//获得数据的绘画实例//sqlSession = sessionFactory.openSession();}/*** 二级缓存** @throws IOException*/@Testpublic void testSecondGoCache() {UserMapper userMapper1 = sqlSession.getMapper(UserMapper.class);UserMapper userMapper2 = sqlSession.getMapper(UserMapper.class);System.out.println("=========One===========");User user1 = userMapper1.getUserById(42); // 执行sql语句System.out.println(user1);sqlSession.commit();System.out.println("=========Two===========");User user2 = userMapper2.getUserById(42); // 不执行sql语句,走缓存System.out.println(user2);}/*** 二级缓存,不走缓存,两个sql之间执行增删改** @throws IOException*/@Testpublic void testSecondNoCache() {UserMapper userMapper1 = sqlSession.getMapper(UserMapper.class);UserMapper userMapper2 = sqlSession.getMapper(UserMapper.class);System.out.println("=========One===========");User user1 = userMapper1.getUserById(42); // 执行sql语句System.out.println(user1);sqlSession.commit();System.out.println("************增删改**************");userMapper1.deleteUserById(41);sqlSession.commit();System.out.println("=========Two===========");User user2 = userMapper2.getUserById(42); // 执行sql语句System.out.println(user2);}/*** 二级缓存,不走缓存,不同的sqlSessionFactory** @throws IOException*/@Testpublic void testSecondNoCache2() throws IOException {String resource = "mybatis-config.xml";InputStream inputStream1 = Resources.getResourceAsStream(resource);InputStream inputStream2 = Resources.getResourceAsStream(resource);//工厂1SqlSessionFactory sessionFactory1 = new SqlSessionFactoryBuilder().build(inputStream1);SqlSession sqlSession1 = sessionFactory1.openSession();UserMapper userMapper1 = sqlSession1.getMapper(UserMapper.class);//工厂2SqlSessionFactory sessionFactory2 = new SqlSessionFactoryBuilder().build(inputStream2);SqlSession sqlSession2 = sessionFactory2.openSession();UserMapper userMapper2 = sqlSession2.getMapper(UserMapper.class);System.out.println("=========One===========");User user1 = userMapper1.getUserById(42); // 执行sql语句System.out.println(user1);sqlSession1.commit();System.out.println("=========Two===========");User user2 = userMapper2.getUserById(42); // 执行sql语句System.out.println(user2);}@Afterpublic void close() throws IOException {//inputStream.close();//sqlSession.close();}}
总结:
1、一级缓存
范围:一级缓存范围是sqlSession
配置:默认开启
走缓存:同一个sqlsession执行同一条sql
不走缓存:不同sqlSession 或 两次查询之间执行了增删改
2、二级缓存
范围:二级缓存范围是sqlSessionFactory
配置:<cache></cache>
走缓存:同一个sqlSessionFactrory,sqlsession执行commit或close
不走缓存:不同sqlSessionFactrory 或 两次查询之间执行了增删改
开启缓存:
1.在SqlMapConfig.xml 文件开启二级缓存,默认开启,可以省略
<settings><!-- 开启二级缓存的支持 --><setting name="cacheEnabled" value="true"/>
</settings>
2.配置相关的Mapper映射文件 开启局部缓存(必须有)
<!-- 开启二级缓存的支持 --><cache></cache>
相关文章:
MyBatis的缓存!!!!
为什么使用缓存? 首次访问时,查询数据库,并将数据存储到内存中;再次访问时直接访问缓存,减少IO、硬盘读写次数、提高效率 Mybatis中的一级缓存和二级缓存? 一级缓存: 它指的是mybatis中的SqlSession对象的…...
ToB还是ToC?工业级与消费级AR眼镜都能干什么?
随着科技的飞速发展,增强现实(AR)技术逐渐融入我们的日常生活。我国AR眼镜消费市场分为消费级和工业级应用。其中消费级主要分为游戏、影视、直播以及社交购物与旅游;工业级主要应用于医疗、汽车、工业、船舶、电力和仓储等专业领…...
设计模式-Java版本
文章目录 前言设计原则单一职责原则开闭原则里氏替换原则迪米特法则接口隔离原则依赖倒置原则 设计模式构建类型工厂模式抽象工厂建造者模式原型模式单例模式 结构型适配器模式桥接模式组合模式装饰器模式代理模式外观模式享元模式 行为模式责任链模式命令模式迭代器模式中介模…...
数据库中如何修改和删除字段
PS:在"[ ]"中的所有数据都是可修改的 添加表字段 ALTER TABLE [表名] add [添加的新字段名] [添加新的数据类型] COMMENT [昵称] alter:修改(后面一般加table表示修改表) add:添加一个字段 在这个里面c…...
在 Golang 应用程序中管理多个数据库
掌握在 Golang 项目中处理多个数据库的艺术 在当前软件开发领域中,处理单个应用程序内的多个数据库的需求越来越普遍。具有强大功能的 Golang 是处理此类任务的绝佳解决方案,无论您是与多个数据源合作还是仅为增强组织和可扩展性而分隔数据。在本文中&a…...
理解开源协议GPL、MIT、BSD、Apache License
开源协议是一种法律文件,规定了使用、修改和分享开源软件的规则和条件。以下是一些常见的开源协议及其相同点和区别:GPL(GNU General Public License):GPL 是一种比较严格的开源协议,要求使用者如果对开源软…...
Talk | 北京大学博士生汪海洋:通向3D感知大模型的前置方案
本期为TechBeat人工智能社区第559期线上Talk。 北京时间12月28日(周四)20:00,北京大学博士生—汪海洋的Talk已准时在TechBeat人工智能社区开播! 他与大家分享的主题是: “通向3D感知大模型的前置方案”,介绍了他的团队在3D视觉大模型的前置方…...
【C语言数组传参】规则详解
目录 数组传参介绍 数组传参规则 数组传参的实参 特殊情况一:sizeof(数组名) 特殊情况二:&数组名 数组传参的形参 数组传参使用数组名作为形参接收 形参如果是⼀维数组 形参如果是⼆维数组 数组传参使用指针作为形参…...
【Linux】Ubuntu22.04版本下实现gcc版本的快速切换
本文将介绍如何在Ubuntu22.04版本下实现gcc版本的快速切换。 本文首发于 ❄️慕雪的寒舍 前言 有的时候,不同版本的gcc会造成一些细微的差异,导致相关的一些工具不兼容,比如用于单元测试覆盖率生成的gcov/lcov工具,在不同的gcc版…...
使用Node Exporter采集主机数据
安装 Node Exporter 在 Prometheus 的架构设计中,Prometheus Server 并不直接服务监控特定的目标,其主要任务负责数据的收集,存储并且对外提供数据查询支持。因此为了能够能够监控到某些东西,如主机的 CPU 使用率,我们…...
Django 文件上传(十二)
当 Django 处理文件上传时,文件数据最终会被放置在 request.FILES 。 查看文档:文件上传 | Django 文档 | Django Django工程如下: 创建本地存储目录 在static/应用目录下创建uploads目录用于存储接收上传的文件 在settings.py 配置静态目…...
k8s的陈述式资源管理
k8s的陈述式资源管理: 命令行:kubectl命令行工具 优点:90%以上的场景都可以满足 对资源的增,删,查比较方便,对改不是很友好 缺点: 命令比较冗长,复杂,难记 声明式&…...
electron-builder 打包exe后白屏
项目用的是An Electron application with Vue3 and TypeScript。 Debug运行项目没问题,可以显示页面。不过有浏览器控制台显示错误: Unable to load preload script:preload/index.js Unable to load preload script 翻译后:无法…...
mvvm,vue双向数据绑定的原理
MVVM (Model-View-ViewModel) 是一种设计模式,主要用于构建用户界面。在 MVVM 中,Model 表示应用程序的数据,View 表示用户界面,而 ViewModel 是 Model 和 View 之间的连接器。MVVM 的核心思想是将视图与模型分离,使它…...
【Java中序列化的原理是什么(解析)】
🍁序列化的原理是什么? 🍁典型-----解析🍁拓展知识仓🍁Serializable 和 Externalizable 接门有何不同? 🍁如果序列化后的文件或者原始类被篡改,还能被反序列化吗?🍁serialVersionU…...
冠赢互娱基于 OpenKrusieGame 实现游戏云原生架构升级
作者:力铭 关于冠赢互娱 冠赢互娱是一家集手游、网游、VR 游戏等研发、发行于一体的游戏公司,旗下官方正版授权的传奇类手游——《仙境传奇》系列深受广大玩家们的喜爱。基于多年 MMORPG 类型游戏的自研与运营经验,冠赢互娱正式推出了 2D M…...
Mybatis 动态 SQL - trim, where, set
之前的例子都巧妙地避开了一个臭名昭著的动态SQL挑战。考虑一下如果我们回到之前的“if”例子,但这次我们将“ACTIVE 1”也作为一个动态条件。 <select id"findActiveBlogLike"resultType"Blog">SELECT * FROM BLOGWHERE<if test&qu…...
大模型系列:OpenAI使用技巧_使用OpenAI进行K-means聚类
文章目录 1. 使用K-means算法找到聚类2. 聚类中的文本样本和聚类的命名让我们展示每个聚类中的随机样本。 我们使用一个简单的k-means算法来演示如何进行聚类。聚类可以帮助发现数据中有价值的隐藏分组。数据集是在 Get_embeddings_from_dataset Notebook中创建的。 # 导入必要…...
共享单车之数据分析
文章目录 第1关:统计共享单车每天的平均使用时间第2关:统计共享单车在指定地点的每天平均次数第3关:统计共享单车指定车辆每次使用的空闲平均时间第4关:统计指定时间共享单车使用次数第5关:统计共享单车线路流量 第1关…...
Spring的Bean你了解吗
Bean的配置 Spring容器支持XML(常用)和Properties两种格式的配置文件 Spring中XML配置文件的根元素是,中包含了多个子元素,每个子元素定义了一个Bean,并描述了该Bean如何装配到Spring容器中 元素包含了多个属性以及子元素,常用属性及子元素如下所示 i…...
C++初阶-list的底层
目录 1.std::list实现的所有代码 2.list的简单介绍 2.1实现list的类 2.2_list_iterator的实现 2.2.1_list_iterator实现的原因和好处 2.2.2_list_iterator实现 2.3_list_node的实现 2.3.1. 避免递归的模板依赖 2.3.2. 内存布局一致性 2.3.3. 类型安全的替代方案 2.3.…...
从零实现富文本编辑器#5-编辑器选区模型的状态结构表达
先前我们总结了浏览器选区模型的交互策略,并且实现了基本的选区操作,还调研了自绘选区的实现。那么相对的,我们还需要设计编辑器的选区表达,也可以称为模型选区。编辑器中应用变更时的操作范围,就是以模型选区为基准来…...
江苏艾立泰跨国资源接力:废料变黄金的绿色供应链革命
在华东塑料包装行业面临限塑令深度调整的背景下,江苏艾立泰以一场跨国资源接力的创新实践,重新定义了绿色供应链的边界。 跨国回收网络:废料变黄金的全球棋局 艾立泰在欧洲、东南亚建立再生塑料回收点,将海外废弃包装箱通过标准…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
NLP学习路线图(二十三):长短期记忆网络(LSTM)
在自然语言处理(NLP)领域,我们时刻面临着处理序列数据的核心挑战。无论是理解句子的结构、分析文本的情感,还是实现语言的翻译,都需要模型能够捕捉词语之间依时序产生的复杂依赖关系。传统的神经网络结构在处理这种序列依赖时显得力不从心,而循环神经网络(RNN) 曾被视为…...
QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
