mybaits(8)-缓存机制

缓存机制

  • 1、mybatis缓存
  • 2、一级缓存
    • 2.1 开启一级缓存
    • 2.2 一级缓存失效
  • 3、二级缓存
    • 3.1 开启二级缓存
    • 3.2 二级缓存什么时候失效
    • 3.3 二级缓存的相关配置
  • 4、MyBatis集成EhCache

1、mybatis缓存

缓存:cache
缓存的作用:通过减少IO的方式,来提高程序的执行效率。
mybatis的缓存:将select语句的查询结果放到缓存(内存)当中,下一次还是这条select语句的话,直接从缓存中取,不再查数据库。一方面是减少了IO。另一方面不再执行繁琐的查找算法。效率大大提升。
mybatis缓存包括:
● 一级缓存:将查询到的数据存储到SqlSession中。
● 二级缓存:将查询到的数据存储到SqlSessionFactory中。
● 或者集成其它第三方的缓存:比如EhCache【Java语言开发的】、Memcache【C语言开发的】等。
缓存只针对于DQL语句,也就是说缓存机制只对应select语句。

2、一级缓存

2.1 开启一级缓存

一级缓存默认是开启的。不需要做任何配置。
原理:只要使用同一个SqlSession对象执行同一条SQL语句,就会走缓存。
测试:

  @Testpublic void test2() throws  Exception{SqlSession sqlSession = MybatisUtils.openSession();CarMapper mapper = sqlSession.getMapper(CarMapper.class);Car car = mapper.selectByid(8);System.out.println(car);Car car1 = mapper.selectByid(8);System.out.println(car1);sqlSession.close();}

在这里插入图片描述

只执行了一次sql语句查询。

2.2 一级缓存失效

什么情况下不走缓存?
● 第一种:不同的SqlSession对象。
● 第二种:查询条件变化了。
一级缓存失效情况包括两种:
● 第一种:第一次查询和第二次查询之间,手动清空了一级缓存。

 @Testpublic void test2() throws  Exception{SqlSession sqlSession = MybatisUtils.openSession();CarMapper mapper = sqlSession.getMapper(CarMapper.class);Car car = mapper.selectByid(8);System.out.println(car);sqlSession.clearCache();Car car1 = mapper.selectByid(8);System.out.println(car1);sqlSession.close();}

在这里插入图片描述
第二种:第一次查询和第二次查询之间,执行了增删改操作。【这个增删改和哪张表没有关系,只要有insert delete update操作,一级缓存就失效。】

 @Testpublic void test2() throws  Exception{SqlSession sqlSession = MybatisUtils.openSession();CarMapper mapper = sqlSession.getMapper(CarMapper.class);Car car = mapper.selectByid(8);System.out.println(car);mapper.InsertClazz(1003,"四班");Car car1 = mapper.selectByid(8);System.out.println(car1);sqlSession.close();}

在这里插入图片描述

3、二级缓存

3.1 开启二级缓存

二级缓存的范围是SqlSessionFactory。
使用二级缓存需要具备以下几个条件:

  1. 全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。默认就是true,无需设置。
  2. 在需要使用二级缓存的SqlMapper.xml文件中添加配置:
  3. 使用二级缓存的实体类对象必须是可序列化的,也就是必须实现java.io.Serializable接口
  4. SqlSession对象关闭或提交之后,一级缓存中的数据才会被写入到二级缓存当中。此时二级缓存才可用。
    只有4个同时满足,才会开启二级缓存

Carmapper.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">
<!--namespace先随意写一个-->
<mapper namespace="com.cky.mapper.CarMapper">
<!--    cache 表示当前配置文件 开启二级缓存-->
<cache/><select id="selectByid" resultType="car">select * from t_car where id=#{id}</select>
</mapper>

CarMapper.JAVA 实现序列化接口

package com.cky.pojo;import java.io.Serializable;public class Car implements Serializable {private Integer id;private String carNum;private String brand;private Double guidePrice;private  String produceTime;private String carType;public Car(Integer id, String carNum, String brand, Double guidePrice, String produceTime, String carType) {this.id = id;this.carNum = carNum;this.brand = brand;this.guidePrice = guidePrice;this.produceTime = produceTime;this.carType = carType;}public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}public String getCarNum() {return carNum;}public void setCarNum(String carNum) {this.carNum = carNum;}public String getBrand() {return brand;}public void setBrand(String brand) {this.brand = brand;}public Double getGuidePrice() {return guidePrice;}public void setGuidePrice(Double guidePrice) {this.guidePrice = guidePrice;}public String getProduceTime() {return produceTime;}public void setProduceTime(String produceTime) {this.produceTime = produceTime;}public String getCarType() {return carType;}public void setCarType(String carType) {this.carType = carType;}@Overridepublic String toString() {return "Car{" +"id=" + id +", carNum='" + carNum + '\'' +", brand='" + brand + '\'' +", guidePrice=" + guidePrice +", produceTime='" + produceTime + '\'' +", carType='" + carType + '\'' +'}';}
}

测试类

 @Testpublic void test() throws  Exception{SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));SqlSession sqlSession1 = sqlSessionFactory.openSession();SqlSession sqlSession2 = sqlSessionFactory.openSession();CarMapper mapper = sqlSession1.getMapper(CarMapper.class);CarMapper mapper1 = sqlSession2.getMapper(CarMapper.class);Car car = mapper.selectByid(7);System.out.println(car);//只有关闭sqlsession1 二级缓存才会启用,把一级缓存的内容转移到二级缓存中sqlSession1.close();
//        Thread.sleep(10*1000);//即使在sleep此期间 我通过数据库软件修改了值,但是由于此时关闭了sqlsession1 二级缓存已经启用,所以再次查询仍然会从缓存中读取,数据库中修改的数据并不会显示。Car car1 = mapper1.selectByid(7);System.out.println(car1);sqlSession2.close();}

在这里插入图片描述
第二次并没有执行sql,而是从二级缓存中读取了,因为一级缓存关闭,会将其内容保存在二级缓存中。
如果一级缓存没有关闭,二级缓存不会开启

 @Testpublic void test() throws  Exception{SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));SqlSession sqlSession1 = sqlSessionFactory.openSession();SqlSession sqlSession2 = sqlSessionFactory.openSession();CarMapper mapper = sqlSession1.getMapper(CarMapper.class);CarMapper mapper1 = sqlSession2.getMapper(CarMapper.class);Car car = mapper.selectByid(7);System.out.println(car);//        Thread.sleep(10*1000);//即使在sleep此期间 我通过数据库软件修改了值,但是由于此时关闭了sqlsession1 二级缓存已经启用,所以再次查询仍然会从缓存中读取,数据库中修改的数据并不会显示。Car car1 = mapper1.selectByid(7);System.out.println(car1);//只有关闭sqlsession1 二级缓存才会启用,把一级缓存的内容转移到二级缓存中sqlSession1.close();sqlSession2.close();}

在这里插入图片描述
执行了两次。

3.2 二级缓存什么时候失效

进行了增删改的操作,就会导致二级缓存清空,二级缓存此时会失效。
注意:即使增删改的不是不是同一张表,但是只要是同一个sqlsessionfactory创建出来的sqlsession,进行了增删改,都会导致其失效,此时,一级缓存一定也失效

  @Testpublic void test1() throws  Exception{SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));SqlSession sqlSession1 = sqlSessionFactory.openSession();SqlSession sqlSession2 = sqlSessionFactory.openSession();SqlSession sqlSession3 = sqlSessionFactory.openSession();CarMapper mapper = sqlSession1.getMapper(CarMapper.class);CarMapper mapper1 = sqlSession2.getMapper(CarMapper.class);CarMapper mapper2 = sqlSession3.getMapper(CarMapper.class);Car car = mapper.selectByid(7);System.out.println(car);//只有关闭sqlsession1 二级缓存才会启用,把一级缓存的内容转移到二级缓存中sqlSession1.close();//增操作 ,失效int row = mapper2.InsertClazz(1002, "三班");sqlSession3.commit();System.out.println(row);Car car1 = mapper1.selectByid(7);System.out.println(car1);sqlSession2.close();sqlSession3.close();}
}

在这里插入图片描述

3.3 二级缓存的相关配置

在这里插入图片描述

  1. eviction:指定从缓存中移除某个对象的淘汰算法。默认采用LRU策略。
    a. LRU:Least Recently Used。最近最少使用。优先淘汰在间隔时间内使用频率最低的对象。(其实还有一种淘汰算法LFU,最不常用。)
    b. FIFO:First In First Out。一种先进先出的数据缓存器。先进入二级缓存的对象最先被淘汰。
    c. SOFT:软引用。淘汰软引用指向的对象。具体算法和JVM的垃圾回收算法有关。
    d. WEAK:弱引用。淘汰弱引用指向的对象。具体算法和JVM的垃圾回收算法有关。
  2. flushInterval:
    a. 二级缓存的刷新时间间隔。单位毫秒。如果没有设置。就代表不刷新缓存,只要内存足够大,一直会向二级缓存中缓存数据。除非执行了增删改。
  3. readOnly:
    a. true:多条相同的sql语句执行之后返回的对象是共享的同一个。性能好。但是多线程并发可能会存在安全问题。
    b. false:多条相同的sql语句执行之后返回的对象是副本,调用了clone方法。性能一般。但安全。
  4. size:
    a. 设置二级缓存中最多可存储的java对象数量。默认值1024。

4、MyBatis集成EhCache

集成EhCache是为了代替mybatis自带的二级缓存。一级缓存是无法替代的。
mybatis对外提供了接口,也可以集成第三方的缓存组件。比如EhCache、Memcache等。都可以。
EhCache是Java写的。Memcache是C语言写的。所以mybatis集成EhCache较为常见,按照以下步骤操作,就可以完成集成:
第一步:引入mybatis整合ehcache的依赖。

<!--mybatis集成ehcache的组件-->
<dependency><groupId>org.mybatis.caches</groupId><artifactId>mybatis-ehcache</artifactId><version>1.2.2</version>
</dependency>

第二步:在类的根路径下新建echcache.xml文件,并提供以下配置信息。

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd"updateCheck="false"><!--磁盘存储:将缓存中暂时不使用的对象,转移到硬盘,类似于Windows系统的虚拟内存--><diskStore path="e:/ehcache"/><!--defaultCache:默认的管理策略--><!--eternal:设定缓存的elements是否永远不过期。如果为true,则缓存的数据始终有效,如果为false那么还要根据timeToIdleSeconds,timeToLiveSeconds判断--><!--maxElementsInMemory:在内存中缓存的element的最大数目--><!--overflowToDisk:如果内存中数据超过内存限制,是否要缓存到磁盘上--><!--diskPersistent:是否在磁盘上持久化。指重启jvm后,数据是否有效。默认为false--><!--timeToIdleSeconds:对象空闲时间(单位:秒),指对象在多长时间没有被访问就会失效。只对eternal为false的有效。默认值0,表示一直可以访问--><!--timeToLiveSeconds:对象存活时间(单位:秒),指对象从创建到失效所需要的时间。只对eternal为false的有效。默认值0,表示一直可以访问--><!--memoryStoreEvictionPolicy:缓存的3 种清空策略--><!--FIFO:first in first out (先进先出)--><!--LFU:Less Frequently Used (最少使用).意思是一直以来最少被使用的。缓存的元素有一个hit 属性,hit 值最小的将会被清出缓存--><!--LRU:Least Recently Used(最近最少使用). (ehcache 默认值).缓存的元素有一个时间戳,当缓存容量满了,而又需要腾出地方来缓存新的元素的时候,那么现有缓存元素中时间戳离当前时间最远的元素将被清出缓存--><defaultCache eternal="false" maxElementsInMemory="1000" overflowToDisk="false" diskPersistent="false"timeToIdleSeconds="0" timeToLiveSeconds="600" memoryStoreEvictionPolicy="LRU"/></ehcache>

第三步:修改SqlMapper.xml文件中的标签,添加type属性。

<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

测试类:跟之前没区别

 @Testpublic void test() throws  Exception{SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));SqlSession sqlSession1 = sqlSessionFactory.openSession();SqlSession sqlSession2 = sqlSessionFactory.openSession();CarMapper mapper = sqlSession1.getMapper(CarMapper.class);CarMapper mapper1 = sqlSession2.getMapper(CarMapper.class);Car car = mapper.selectByid(7);System.out.println(car);sqlSession1.close();
//        Thread.sleep(10*1000);//即使在sleep此期间 我通过数据库软件修改了值,但是由于此时关闭了sqlsession1 二级缓存已经启用,所以再次查询仍然会从缓存中读取,数据库中修改的数据并不会显示。Car car1 = mapper1.selectByid(7);System.out.println(car1);//只有关闭sqlsession1 二级缓存才会启用,把一级缓存的内容转移到二级缓存中sqlSession2.close();}

在这里插入图片描述

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

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

相关文章

2024妈妈杯mathorcup数学建模C题 物流网络分拣中心货量预测及人员排班

一、数据预处理 数据清洗是指对数据进行清洗和整理&#xff0c;包括删除无效数据、缺失值填充、异常值检测和处理等。数据转换是指对数据进行转换和变换&#xff0c;包括数据缩放、数据归一化、数据标准化等。数据整理是指对数据进行整理和归纳&#xff0c;包括数据分组、数据聚…

PDF转TXT ChatGPT编程

1.目的 在Z-library找到一本书&#xff0c;只不过是PDF格式的&#xff0c;看的时候体验不好&#xff0c;还没有办法保存记录&#xff0c;就想着能不能转成txt格式放到手机自带的小说软件中看。 不想去网上找相关的软件&#xff0c;可以还需要付钱&#xff0c;所以尝试用ChatGP…

springcloud-fegin 组件调用

一、Feign 概述 Feign是Netflix开发的声明式、模板化的HTTP客户端&#xff0c; Feign可以帮助我们更快捷、优雅地调用HTTP API。 在Spring Cloud中&#xff0c;使用Feign非常简单——创建一个接口&#xff0c;并在接口上添加一些注解&#xff0c;代码就完成了。Feign支持多种…

R: 支持向量机(Support Vector Machine,简称SVM)

在数据科学和机器学习领域中&#xff0c;支持向量机&#xff08;Support Vector Machine&#xff0c;简称SVM&#xff09;是一种强大的监督学习算法&#xff0c;常用于分类和回归分析。它的优点之一是可以适用于复杂的数据集&#xff0c;并且在高维空间中表现良好。在本文中&am…

【示例】MySQL-MySQL中常见的锁

前言 本文主要讲述MySQL中常见的锁。 总结 | 各类别锁的名字 锁级别锁名字解释全局锁read lock全局锁只有可读锁表级锁 - 表锁read lock 表共享读锁write lock 表独占写锁表级锁 - 元数据锁&#xff08;meta data lock&#xff0c;MDL&#xff09;SHARED_READ_ONLYSHARED_NO…

OSPF实验

需求&#xff1a; 1、R1-R3为区域0&#xff0c;R3到R4为区域1&#xff1b;其中R3的环回也在区域0&#xff0c;P1-R3分别有一个环回接口 2、R1-R3 R3为DR设备&#xff0c;没有BDR 3、R4环回地址已固定&#xff0c;其他所有网段使用192.168.1.0/24进行合理分配 4、R4环回不能…

【golang】动态生成微信小程序二维码实战下:golang 生成 小程序二维码图片 并通过s3协议上传到对象存储桶 | 腾讯云 cos

项目背景 在自研的系统&#xff0c;需要实现类似草料二维码的功能 将我们自己的小程序&#xff0c;通过代码生成相想要的小程序二维码 代码已经上传到 Github 需要的朋友可以自取 https://github.com/ctra-wang/wechat-mini-qrcode 一、生成Qrcode并提交到对象存储 通过源生A…

Kubernetes(k8s):深入理解 Kubernetes 中的污点(Taints)与容忍度(Tolerations)

Kubernetes&#xff08;k8s&#xff09;&#xff1a;深入理解 Kubernetes 中的污点&#xff08;Taints&#xff09;与容忍度&#xff08;Tolerations&#xff09; 1、污点&#xff08;Taints&#xff09;2、容忍度&#xff08;Tolerations&#xff09;3、示例演示-测试污点的具…

自动化测试(selenium篇)

这次我们来介绍selenium 我们主要来讲解这几个要点 1.什么是自动化测试 2.什么是selenium 3.为什么来讲selenium 4.selenium的环境搭建 5.selenium的 API 1.什么是自动化测试 自动化测试指软件测试的自动化&#xff0c;在预设状态下运行应用程序或者系统&#xff0c;预设条…

蓝宝石衬底材料具有广阔消费市场 行业景气度良好

蓝宝石衬底材料具有广阔消费市场 行业景气度良好 衬底是由半导体单晶材料制造而成的晶圆片&#xff0c;既可以直接进入晶圆制造环节生产半导体器件&#xff0c;也可以进行外延工艺加工生产外延片&#xff0c;是电子元件的主体结构和支撑载体。蓝宝石衬底材料具有良好的透光性、…

burpsuite最新版2024.3.1安装

burpsuite最新版安装 环境 windows jdk22 BurpLoaderKeygen.jar burpsuite profression 2024.3.1 链接 链接&#xff1a;https://pan.baidu.com/s/1N6nggZZezg8y1FHpgwJmeg 提取码&#xff1a;n6uqjdk以及破戒方式这里不做介绍 注意事项 使用BurpLoaderKeygen.jar 破解之后…

Windows 2003 R2与Windows 2022建立域信任报错:本地安全机构无法跟域控制器获得RPC连接。请检查名称是否可以解析,服务器是否可用。

在Windows Server 2003 R2与Windows Server 2022之间建立域信任时遇到“本地安全机构无法与域控制器获得RPC连接”的错误&#xff0c;可能是由于以下几种原因&#xff1a; DNS 解析问题&#xff1a; 确保源域和目标域的DNS配置正确&#xff0c;能够互相解析对方的域名和IP地址。…

多语言婚恋交友APP开发流程一览

近年来&#xff0c;随着全球化的发展和人们对跨文化交流的需求增加&#xff0c;多语言婚恋交友APP的需求逐渐增长。开发这类APP需要考虑到不同语言和文化下用户的需求&#xff0c;涉及到一系列独特的流程和挑战。本文将从专家角度为您解析多语言婚恋交友APP的开发流程&#xff…

【虚幻引擎】DTProjectSettings 蓝图获取基本项目配置插件使用说明 获取项目命名,项目版本,公司名,公司识别名,主页,联系方式

本插件可以使用蓝图获取到项目的一些基本配置&#xff0c;如获取&#xff1a;公司名、公司识别名、版权声明、描述、主页、许可条款、隐私政策、项目ID、项目命名、项目版本、支持联系方式、项目显示标题、项目调试标题信息、应保留窗口宽高比、使用无边框窗口、以VR启动、允许…

【Vue3进阶】- 第2学堂小商城项目后端准备和接口文档

简介 在大多数前端项目开发中&#xff0c;都需要与后端进行接口交互&#xff0c;后端通常会以文档的形式提供接口信息&#xff0c;前端开发者通过阅读这些文档&#xff0c;了解后端接口的功能和使用方法&#xff0c;从而实现数据的获取和提交等功能。 第二学堂小商城教程后端…

03攻防世界-unserialize3

根据题目可以看出&#xff0c;这是个反序列化的题目 打开网址观察题目可以看到这里是php的代码&#xff0c;那么也就是php的反序列化 本题需要利用反序列化字符串来进行解题&#xff0c;根据源码提示我们需要构造code。 序列化的意思是&#xff1a;是将变量转换为可保存或传输…

MongoDB爬虫:(某扑)实战

https://bbs.hupu.com/bxj网页地址: https://bbs.hupu.com/bxj 然后我们在网页上定义帖子名称、帖子链接、创建时间、回复数、最后回复用户...... 除此之外,我们发现虎扑步行街最多显示的页数(20): 、 当我们打开第3页的时候,网页的URL的地址变为了:https://bbs.hupu.…

vmware虚拟机进不去系统补救

更新了虚拟机里面工具和资料&#xff0c;进行了磁盘整理和压缩&#xff0c;虚拟机运行进不去系统了。 网站找的修复方法均不可行。补救措施&#xff1a;利用DiskGenius.exe&#xff08;要用高版本不然复制的时候就知道了&#xff09; DG1342.rar - 蓝奏云 加载虚拟硬盘 2008x…

Rocky(Centos)数据库等高并发或高io应用linux系统调优,及硬件问题排查(含网络、磁盘、系统监控)

一、系统参数优化 默认的最大打开文件数是1024.不满足生产环境的要求。按照如下配置&#xff1a; 1、修改 systemctl管理的 servie 资源限制 编辑/etc/systemd/system.conf # 全局的打开文件数 DefaultLimitNOFILE2097152 # 全局打开进程数 DefaultLimitNPROC655352、调整系…

文章解读与仿真程序复现思路——电力系统自动化EI\CSCD\北大核心《基于分解算法与元学习结合的综合能源系统负荷预测》

本专栏栏目提供文章与程序复现思路&#xff0c;具体已有的论文与论文源程序可翻阅本博主免费的专栏栏目《论文与完整程序》 论文与完整源程序_电网论文源程序的博客-CSDN博客https://blog.csdn.net/liang674027206/category_12531414.html 电网论文源程序-CSDN博客电网论文源…