Mybatis(六)之缓存

Mybatis(六)——Mybatis缓存 主要介绍Mybatis缓存的一级和二级缓存的用途和使用条件 阅读详情

Mybatis缓存

这里写图片描述

Mybatis的缓存,包括一级缓存和二级缓存

一级缓存是SqlSession级别的缓存。在操作数据库时需要构造 sqlSession对象,在对象中有一个数据结构(HashMap)用于存储缓存数据。不同的sqlSession之间的缓存数据区域(HashMap)是互相不影响的。
.
二级缓存是mapper级别的缓存,多个SqlSession去操作同一个Mapper的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。

一级缓存是默认使用的。 二级缓存需要手动开启。


一级缓存(SqlSession级别)

这里写图片描述
第一次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,如果没有,从数据库查询用户信息。
得到用户信息,将用户信息存储到一级缓存中。

如果sqlSession去执行commit操作(执行插入、更新、删除),清空SqlSession中的一级缓存,这样做的目的为了让缓存中存储的是最新的信息,避免脏读。

第二次发起查询用户id为1的用户信息,先去找缓存中是否有id为1的用户信息,缓存中有,直接从缓存中获取用户信息。

测试代码1

@Test
public void testLevelOneCache() {
    //......
    User user1 = userMapper.findUserById(1);
    User user2 = userMapper.findUserById(1);
    //......
}

这里写图片描述

小结:由日志信息可知,进行两次相同的查询语句,只进行一次数据库查询,说明存在一级缓存

测试代码2

@Test
public void testLevelOneCache() {
    //......
    User user1 = userMapper.findUserById(1);
    userMapper.addUser(user1);
    User user2 = userMapper.findUserById(1);
    //......
}

这里写图片描述

小结:在两次相同的查询之间进行插入操作,导致插入后清除一级缓存,第二次查询便得再次查询数据库


二级缓存(Mapper级别)

这里写图片描述

未开启二级缓存

@Test
public void testLevelTwoCache() {
    SqlSession sqlSession1 = sqlSessionFactory.openSession();
    SqlSession sqlSession2 = sqlSessionFactory.openSession();

    UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
    UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);

    User user1 = mapper1.findUserById(1);
    User user2 = mapper2.findUserById(1);

    sqlSession1.close();
    sqlSession2.close();
}

这里写图片描述

小结:一级缓存默认开启,二级缓存没有手动开启,而这是两个sqlsession的查询,所以一级缓存不起作用,查询了两次数据库

开启二级缓存

1.配置全局配置文件

<settings>
    <!-- 开启二级缓存总开关,默认是false -->
    <setting name="cacheEnabled" value="true"/>
</settings>

2.配置映射文件

<!-- 开启二级缓存,默认使用的是PerpetualCache -->
<cache/>
<!--
    cache元素用来开启当前mapper的namespace下的二级缓存,该元素的属性设置如下:

    flushInterval:刷新间隔,可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段,默认情况下是不设置的,也就是没有刷新间隔,缓存仅仅调用语句时刷新。
    size:缓存数目,可以被设置为任意正整数,要记住你的缓存对象数目和你运行环境可用内存资源数目,默认值是1024.
    readOnly:只读,属性可以被设置为true或false,只读的缓存会给所有调用者返回缓存对象的相同实例,因此这些对象不能被修改。这提供了很重要的性能优势,可读写的缓存会返回缓存对象的拷贝(通过序列化),这会慢一些,但是安全,因此默认是false。
    eviction:收回策略,默认为LRU,有如下几种:
        LRU:最近最少使用的策略,移除最长时间不被使用的对象。
        FIFO:先进先出策略,按对象进入缓存的顺序来移除它们。
        SOFT:软引用策略,移除基于垃圾回收器状态和软引用规则的对象。
        WEAK:弱引用策略,更积极地移除基于垃圾收集器状态和弱引用规则的对象。
-->

3.确保po类实现序列化

public class User implements Serializable {
    ...
}

注意:使用二级缓存时,与查询结果映射的java对象必须实现java.io.Serializable接口的序列化和反序列化操作,如果存在父类,其成员都需要实现序列化接口,实现序列化接口是为了对缓存数据进行序列化和反序列化操作,因为二级缓存数据存储介质多种多样,不一定在内存,有可能是硬盘或者远程服务器。

测试代码1

@Test
public void testLevelTwoCache() {
    SqlSession sqlSession1 = sqlSessionFactory.openSession();
    SqlSession sqlSession2 = sqlSessionFactory.openSession();

    UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
    UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);

    User user1 = mapper1.findUserById(1);
    sqlSession1.commit();
    User user2 = mapper2.findUserById(1);

    sqlSession2.close();
}

这里写图片描述

小结:两个的sqlsession查询相同内容,只查询了一次数据库,说明使用了二级缓存

测试代码2

@Test
public void testLevelTwoCache() {
    SqlSession sqlSession1 = sqlSessionFactory.openSession();
    SqlSession sqlSession2 = sqlSessionFactory.openSession();
    SqlSession sqlSession3 = sqlSessionFactory.openSession();

    UserMapper mapper1 = sqlSession1.getMapper(UserMapper.class);
    UserMapper mapper2 = sqlSession2.getMapper(UserMapper.class);
    UserMapper mapper3 = sqlSession3.getMapper(UserMapper.class);

    User user1 = mapper1.findUserById(1);
    sqlSession1.commit();
    mapper3.addUser(user1);
    sqlSession3.commit();
    User user2 = mapper2.findUserById(1);

    sqlSession1.close();
    sqlSession2.close();
    sqlSession3.close();
}

这里写图片描述

小结:说明二级缓存会在增加、删除、修改后清除缓存

禁用二级缓存

在statement中设置userCache=false,可以禁用当前select语句的二级缓存,即每次查询都是去数据库中查询,默认情况下是true,即该statement使用二级缓存。
这里写图片描述

刷新二级缓存

在statement中设置flushCache=true可以刷新当前的二级缓存,默认情况下如果是select语句,那么flushCache是false。如果是insert、update、delete语句,那么flushCache是true。这也就是为什么默认情况下进行增删改会使二级缓存失效。

1.如果查询语句设置成true,那么每次查询都是去数据库查询,即意味着该查询的二级缓存失效。
2.如果查询语句设置成false,即使用二级缓存,那么如果在数据库中修改了数据,而缓存数据还是原来的,这个时候就会出现脏读。

这里写图片描述


整合Ehcache

Ehcache是一个分布式缓存。

分布式缓存

系统为了提高性能,通常会对系统采用分布式部署(集群部署方式)

这里写图片描述
不使用分布式缓存,缓存的数据在各个服务单独存储,不方便开发。所以要使用分布式缓存对缓存数据进行集中式管理。

问题:Mybatis自身无法实现分布式缓存,需要和其它分布式缓存框架进行整合。

整合思路(重点)

Mybatis提供了一个cache接口,同时它自己有一个默认的实现类PerpetualCache。

通过实现cache接口可以实现mybatis缓存数据通过其他缓存数据库整合,mybatis的特长是sql,缓存数据管理不是mybatis的特长,为了提高mybatis的性能,所以需要mybatis和第三方缓存数据库整合,比如ehcache、memcache、redis等

整合ehcache的步骤

第一步:引入ehcache的jar包
这里写图片描述
第二步:在mapper映射文件中,配置cache标签的type为ehcache对cache接口的实现类类型

<!-- 开启二级缓存,默认使用的是PerpetualCache -->
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>

第三步:加入ehcache的配置文件ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
    <!-- 缓存数据要存放的磁盘地址 -->
    <diskStore path="F:\develop\ehcache" />

    <defaultCache maxElementsInMemory="1000"
    maxElementsOnDisk="10000000" eternal="false" overflowToDisk="false"
    timeToIdleSeconds="120" timeToLiveSeconds="120"
    diskExpiryThreadIntervalSeconds="120" memoryStoreEvictionPolicy="LRU">
    </defaultCache>
</ehcache>

应用场景

使用场景:对于访问响应速度要求高,但是实时性不高的查询,可以采用二级缓存技术。

注意:在使用二级缓存的时候,要设置一下刷新间隔(cache标签中有一个flashInterval属性)来定时刷新二级缓存,这个刷新间隔根据具体需求来设置,比如设置30分钟、60分钟等,单位为毫秒。

局限性

Mybatis二级缓存对细粒度的数据级别的缓存实现不好。

场景:对商品信息进行缓存,由于商品信息查询访问量大,但是要求用户每次查询都是最新的商品信息,此时如果使用二级缓存,就无法实现当一个商品发生变化只刷新该商品的缓存信息而不刷新其他商品缓存信息,因为二级缓存是mapper级别的,当一个商品的信息发送更新,所有的商品信息缓存数据都会清空。

解决此类问题,需要在业务层根据需要对数据有针对性的缓存。
比如可以对经常变化的数据操作单独放到另一个namespace的mapper中。

Maxwell中铜导体热损计算的关键步骤与技巧 本文详细介绍了在Maxwell软件中准确计算铜导体热损的关键步骤与实用技巧。重点阐述了如何正确设置涡流场求解器、启用涡流效应、根据工作频率计算并应用肌肤深度以指导网格剖分,以及准确施加激励和定义电流回路。文章还强调了使用温度相关材料属性和进行后处理验证的重要性,旨在帮助工程师获得可靠的热损计算结果,优化产品设计。 阅读详情

相关推荐

RTC 实时时钟实验

如果在 RTC_CR 寄存器中设置了相应的允许位,则在每个TR_CLK 周期中 RTC 产生一个中断(秒中断)。void BKP_WriteBackupRegister(uint16_t BKP_DR, uint16_t Data) // 往备份区域写用户数据的函数 (这个函数的第一个参数就是寄存器的标号了,这个是通过宏定义定义的)存储在 RTC_ALR 寄存器中的可编程时间相比较,如果 RTC_CR 控制寄存器中设置了相应允许位,比较匹配时将产生一个闹钟中断。寄存器操作完成,并同步之后,设置秒钟中断。

m0_55996456的博客 1205

mybatis12--mybatis的cache参数

mybatis的cache参数只适用于mybatis维护缓存。 1、flushInterval(刷新间隔)可以被设置为任意的正整数,而且它们代表一个合理的毫秒形式的时间段。默认情况是不设置,也就是没有刷新间隔,缓存仅仅调用语句时刷新。 2、size(引用数目)可以被设置为任意正整数,要记住你缓存的对象数目和你运行环境的可用内存资源数目。默认值是1024。 3、readOnly(只读)属...

月落孤城的博客 1123

IntelliJ IDEA 中git使用说明书

IntelliJ IDEA 中git使用说明书

junyang2012的博客 5389

Mybatis缓存初知

目录 文章目录 前言 1. 一级缓存 1.1. 什么是一级缓存 1.2. 测试1-同一个SqlSession 1.3.测试2-不同的SqlSession 1.4. 测试3-刷新缓存 1.5. 总结 2. 二级缓存 2.1. 什么是二级缓存 2.2. 配置二级缓存 2.2.1. 全局开关 2.2.2. 分开关 2.2.3. 代码配置 2.2.4. cache 标签配置详解 总结 前言 缓存的重要性是不言而喻的。使用缓存,我们可以避免频繁的与数据库进行交互,尤其是在...

Aaron Fang的专栏 457

数字通信:信源编码、信道编码、调制、物理信道、解调、信道解码、信源解码

在通信系统中,信息的传输通常需要经过一系列的处理步骤,确保数据可以在信道中高效且可靠地传输。以下是信源编码、信道编码、调制、物理信道、解调、信道解码、信源解码的具体含义及其常见技术的解释。

weixin_44012667的博客 4804

使用 STM32F7 和 TensorFlow Lite 开发低功耗人脸识别设备

我们讨论了 STM32F7 的特点和能力,TensorFlow Lite 在 STM32F7 上的应用,以及一些降低功耗的优化技术。- 准备模型:选择合适的人脸识别模型,在 TensorFlow 中进行训练和导出,并使用 TensorFlow Lite 转换为适用于 STM32F7 的量化模型。请注意,上述代码仅展示了如何加载和运行 TensorFlow Lite 模型的方法,实际应用中需要集成人脸检测和识别模型,并根据实际需求进行相应的输入和输出处理。结合这两个工具,我们可以开发出低功耗的人脸识别设备。

weixin_66608063的博客 2586

七,Mybatis缓存

Mybatis缓存: 一,定义: 缓存优化指通过数据优化,提高程序执行效率的有效方式。比如我需要查询某个商品的数据,提取了一次之后,我需要再次进行提取。因为mysql是从硬盘读取数据,硬盘读取数据的速度较慢,同时第一次和第二次提取都返回了相同记录,多次提取也不合理。我们可以把第一次查询到的数据放到内存中,到第二次要提取的时候可直接从内存取值,内存取值速度比硬盘的快至少几十倍。 二,Mybatis缓存机制: 一级缓存默认开启,缓存范围是一个sqlsession会话,范围较小 二级缓存手动开启,范围属于

好多可乐的博客 248

Zemax:初学者的混合模式

光线以序列模式开始,然后接近非序列组件的入口端口。到达入口端口后,光线以非序列模式传播,然后接近出口端口。光线离开出口端口后,我们又回到序列模式。在此博客中,使用混合模式的示例将演示根据您自己的需要复制此工作流程所需的基本设置,以及一些有用的技巧。非序列组件表面类型必须在序列模式和非序列模式下定义。为了定义非序列组件的几何形状,请转到设置->编辑器->非序列,单击非序列编辑器。一旦我们进入非序列组件编辑器:表面 2 上的组件组,找到一个对象类型并进行定义。它能让您兼具序列模式的精确性和非序列模式的灵活性。

jkh920184196的博客 1337

mybatis缓存机制

一级缓存与二级缓存 一级缓存:作用域为session的缓存,当session flush或close之后,该session中的所有缓存就将清空。

develop 811

连接参数详解:Connection Interval, Slave Latency, Supervision Timeout 的协同与调优实战

在低功耗蓝牙(BLE)开发与调试中,Connection Interval(连接间隔)、Slave Latency(从机延迟) 和 Supervision Timeout(监督超时) 是三个核心参数。它们不仅直接影响设备的通信性能、功耗表现和连接稳定性,更是各类技术面试与认证考试的高频考点。本文将从基础概念出发,深入剖析三者的协同机制,结合历年真题解析考点与解题思路,并通过实战案例演示调优方法,快速掌握这一核心知识点。

byte轻骑兵的技术小窝 2761

芒果YOLOv8改进72:动态标签分配策略篇之ATSS:自适应训练样本选择Adaptive Training Sample Selection策略

YOLOv8代码实践|ATSS标签分配策略改进🥭

包括YOLOv5、YOLOv7、YOLOv8等模型改进 2908

MyBatis缓存浅析——MyBatis基础之六

缓存是一种临时存储少量数据至内存或者是磁盘的一种技术.减少数据的加载次数,可以降低工作量,提高程序响应速度。缓存的重要性是不言而喻的。mybatis的缓存将相同查询条件的SQL语句执行一遍后所得到的结果存在内存或者某种缓存介质当中,当下次遇到一模一样的查询SQL时候不在执行SQL与数据库交互,而是直接从缓存中获取结果,减少服务器的压力;尤其是在查询越多、缓存命中率越高的情况下,使用缓存对性能的提高更明显。

在青海看海的企鹅的博客 953

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

六、Mybatis缓存

前言 Mybatis缓存分为一级缓存和二级缓存。一级缓存的作用域是在sqlSession,即一次会话,从开始到关闭。二级缓存的作用域是每个Mapper.xml。默认情况下,只启用了本地的会话缓存,它仅仅对一个会话中的数据进行缓存。要启用二级缓存,只需要在SQL映射文件中添加一行:<cache/>。[Mybatis官方文档-缓存](https://mybatis.org/mybatis-3/zh/sqlmap-xml.html#cache) 一、在pom.xml中添加Ehcache缓存包。 &l

rookie__zhou的博客 130

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

MyBatis(六)MyBatis的缓存

我们通过同一个sqlsession所查询出来的数据,会被缓存,当我们再次通过同一个sqlsession去查询相同的数据的时候,会直接从缓存里面进行查找,并不会从我们的数据库里面重新去查了。一级缓存是SqlSession级别的,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问。会返回缓存对象的拷贝(通过序列化),修改了拷贝后,对象并没有被修改。我们发现查询了两次,但是sql只运行了一次,第一次是从咱们的数据库里面查的,第二次是从缓存里面查的。

超级程序诞生的博客 314

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

Mybatis(六)缓存

二级缓存是存在一个问题的,当对一个表的增删改查不在同一个namespace(即同一个接口中)时,会出现脏读现象,因为二级缓存是Mapper级别的(即一个Mapper接口层面),如果同一个表的修改在其他namespace(即其他Mapper)执行,此时第一个Mapper的二级缓存无法感知到第二个Mapper的二级缓存的改变,所以导致读到未刷新的数据。Mybatis的缓存类使用装饰者模式,Cache接口只有一个基本的实现类,即PrepetualCache类,该类通过一个HasshMap存放缓存对象。

qq_35599414的博客 668

六、MyBatis-缓存机制

MyBatis 包含一个非常强大的查询缓存特性,它可以非常方便地配置和定制。缓存可以极大的提升查询效率。MyBatis系统中默认定义了两级缓存, 一级 缓存和 二级缓存。– 1、默认情况下,只有一级缓存(SqlSession级别的缓存,也称为本地缓存)开启,一级缓存默认实现类org.apache.ibatis.cache.impl.PerpetualCache。– 2、二级缓存需要手动开启和配置,...

weixin_30375427的博客 259

MyBatis学习总结(六)——Mybatis缓存

一、MyBatis缓存介绍   正如大多数持久层框架一样,MyBatis 同样提供了一级缓存和二级缓存的支持 一级缓存: 基于PerpetualCache 的 HashMap本地缓存,其存储作用域为 Session,当 Session flush 或 close 之后,该Session中的所有 Cache 就将清空。   2. 二级缓存与一级缓存其机制相同,默认也是采用 Perpe

nuliPerfect的博客 450

【MyBatis笔记整理六】缓存机制

本篇博客主要讲解 MyBatis 中的 缓存机制,其实 缓存机制 与延迟加载作用是一样的,也是为了减少 Java 应用程序与数据库的交互次数,从而提升程序的运行效率。 在 MyBatis 中有两种缓存:一级缓存和二级缓存。本篇博客主要对这两种缓存展开讲解。

小异常的博客 452

[由零开始] 六、MyBatis二级缓存整合redis

[由零开始] 五、深度理解MyBatis缓存机制优化自定义持久层框架实现自动映射分析现有问题分析使用端调用时的问题作出预期设想并提出问题解决方案实现自动映射 优化自定义持久层框架实现自动映射 首先我们最先知道Mybatis是一个半自动的持久层框架 既然是半自动 那么他可以做到自动的映射到我们的Mapper 我们只需要手动编写sql就可以实现我们想要的对数据库的相应操作 分析现有问题 前几章我们已经...

MrSoon的博客 253

(六)Mybatis 缓存

1. 简介 什么是缓存 存在内存中的临时数据。 将用户经常查询得数据放在缓存(内存)中,用户就不需要在磁盘(关系型数据库数据文件)中查询数据,而是在缓存中查询数据,从而提高查询效率,解决了高并发系统的性能问题。 为什么使用缓存 减少和数据库的交互次数,减少系统开销,提高系统效率。 什么样的数据能使用缓存 经常查询并不经常改变的数据。 2. Mybatis 缓存 Mybatis 包含了一个非常强大的查询缓存特性,它可以非常方便地定制和配置缓存。缓存可以极大地提高查询效率。 Mybati

歪比巴卜 156

mybatis学习笔记六——mybatis缓存cache

mybatis分为一级缓存、二级缓存 语句顺序:先查二级缓存 → 再查一级缓存 → 最后才去数据库查找 一、一级缓存(默认状态开启) SqlSession级别缓存。开启一个SqlSession级别的map进行保存 生效:使用同一个SqlSession并且没有做过增删改(第一次查询与第二次查询之间)、或者手动清除缓存的操作(sqlSession.clearCache();),一...

好幸运 344

mybatis学习六(缓存)

一、简介 缓存是通过将常用数据保存在内存,以便于下次使用时不用访问数据库,而是直接访问缓存,从而提高效率的一种手段 Mybatis缓存分为一级缓存和二级缓存 二、一级缓存 一级缓存是基于SqlSession的,生命周期和SqlSession一致 在同一个 SqlSession 中查询时, MyBatis 会把执行的方法和参数通过算法生成缓存的键值,将键值和查询结果存入一个 Map对象中。...

quge_name_harder的博客 171

MyBatis复习(六):MyBatis二级缓存

Mybatis缓存分为一级缓存和二级缓存 MyBatis一级缓存是默认开启的,数据存储范围是SqlSession会话这个级别,当SqlSession关闭后,缓存就会被清除,生命周期非常短。 MyBatis二级缓存需手动开启,二级缓存存储范围为Mapper Namespace(Mapper映射器的命名空间) MyBatis缓存数据是存储在JVM内存中,它存储对象的本质是利用Map保存缓存数据。 二级缓存运行规则: 二级缓存开启后,默认所有的查询操作均使用缓存 写/插入操作commit提交时,

想好了就去做吧 即便失败了 至少这条路上留下了你的脚印 535

mybatis系列:六、缓存机制

mybatis 缓存机制简单概述一级缓存二级缓存图解开启配置实现序列化:禁用二级缓存刷新缓存Cache参数整合ehcache应用场景局限性 简单概述 为了提高操作数据库的效率,mybatis提供了对缓存的支持,分为一级缓存和二级缓存。 Mybatis一级缓存的作用域是同一个SqlSession,在同一个sqlSession中两次执行相同的sql语句,第一次执行完毕会将数据库中查询的数据写到缓存(内...

laonxs的博客 216

深入理解MyBatis(六)—MyBatis的缓存机制

深入理解MyBatis(六)—MyBatis的缓存机制 频繁的数据库查询操作是非常耗费性能的额,因为数据库查询底层依靠文件存储机制的IO操作,而IO操作的速度相比于内存作要慢几个量级,因此更好的解决方案是把相同的查询语句的结果存储在内存中,下次再查询时直接从内存中读取; 个人主页:tuzhenyu’s page 原文地址:深入理解MyBatis(六)—MyBatis的缓存机

tuzhenyu的博客 687
上一篇: Mybatis(五)之延迟加载
下一篇: Mybatis(七)之整合Spring
章 鱼
博客等级 码龄10年 203粉丝 105原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值