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…...
MongoDB学习和应用(高效的非关系型数据库)
一丶 MongoDB简介 对于社交类软件的功能,我们需要对它的功能特点进行分析: 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具: mysql:关系型数据库&am…...
遍历 Map 类型集合的方法汇总
1 方法一 先用方法 keySet() 获取集合中的所有键。再通过 gey(key) 方法用对应键获取值 import java.util.HashMap; import java.util.Set;public class Test {public static void main(String[] args) {HashMap hashMap new HashMap();hashMap.put("语文",99);has…...
P3 QT项目----记事本(3.8)
3.8 记事本项目总结 项目源码 1.main.cpp #include "widget.h" #include <QApplication> int main(int argc, char *argv[]) {QApplication a(argc, argv);Widget w;w.show();return a.exec(); } 2.widget.cpp #include "widget.h" #include &q…...
根据万维钢·精英日课6的内容,使用AI(2025)可以参考以下方法:
根据万维钢精英日课6的内容,使用AI(2025)可以参考以下方法: 四个洞见 模型已经比人聪明:以ChatGPT o3为代表的AI非常强大,能运用高级理论解释道理、引用最新学术论文,生成对顶尖科学家都有用的…...
网络编程(UDP编程)
思维导图 UDP基础编程(单播) 1.流程图 服务器:短信的接收方 创建套接字 (socket)-----------------------------------------》有手机指定网络信息-----------------------------------------------》有号码绑定套接字 (bind)--------------…...
稳定币的深度剖析与展望
一、引言 在当今数字化浪潮席卷全球的时代,加密货币作为一种新兴的金融现象,正以前所未有的速度改变着我们对传统货币和金融体系的认知。然而,加密货币市场的高度波动性却成为了其广泛应用和普及的一大障碍。在这样的背景下,稳定…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...
Go语言多线程问题
打印零与奇偶数(leetcode 1116) 方法1:使用互斥锁和条件变量 package mainimport ("fmt""sync" )type ZeroEvenOdd struct {n intzeroMutex sync.MutexevenMutex sync.MutexoddMutex sync.Mutexcurrent int…...
从“安全密码”到测试体系:Gitee Test 赋能关键领域软件质量保障
关键领域软件测试的"安全密码":Gitee Test如何破解行业痛点 在数字化浪潮席卷全球的今天,软件系统已成为国家关键领域的"神经中枢"。从国防军工到能源电力,从金融交易到交通管控,这些关乎国计民生的关键领域…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
