MyBatis系统学习篇 - MyBatis的缓存

MyBatis的缓存实现原理主要基于三级缓存机制,包括一级缓存(本地缓存)、二级缓存(全局缓存)和三级缓存(跨会话缓存)。这个缓存在我们实际开发中可以避免我们查询重复的数据,在一定程度上可以帮助我们减少对数据库同一数据的重复查询,也可以在一定程度上使用MyBatis缓存可以帮助我们更好的查询数据和进行数据交互,减少对数据库的数据查询次数吧。

一级缓存

MyBatis一级缓存也可以称作本地缓存,他是SqlSession级别的缓存,默认开启,可以减少我们对数据库的重复查询,当执行查询的时候,查询结果会被存储在SqlSession中的本地存储中,在同一个Session中,如果执行相同的查询,MyBatis会从本地缓存中查找结果,如果找到则直接返回,否则再去数据库中查询并存储到本地缓存中。

一级缓存的实现

// 在MyBatis配置文件中开启一级缓存
<configuration><settings><setting name="localCacheScope" value="SESSION"/></settings>
</configuration>
public static void main(String[] args) {try (SqlSession sqlSession = sqlSessionFactory.openSession()) {EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);// 测试一级缓存Emp emp1 = empMapper.getEmpById(1); // 第一次查询,会从数据库中获取数据Emp emp2 = empMapper.getEmpById(1); // 第二次查询,会从一级缓存中获取数据System.out.println(emp1 == emp2); // 输出:true,说明从一级缓存中获取到了同一个对象}}

一级缓存失效的几种情况:

  • 不同的SqlSession:一级缓存是基于SqlSession的,当使用不同的SqlSession对象执行相同的查询时,一级缓存会失效。因为每个SqlSession都有自己的本地缓存,无法共享缓存数据。

  • 手动清空缓存:通过调用SqlSessionclearCache()方法可以手动清空一级缓存。这样会导致之前缓存的数据被清除,下一次查询会重新从数据库中获取数据。

  • 更新操作:当执行了插入、更新或删除操作时,可能会影响到缓存中的数据。MyBatis会自动将更新操作同步到缓存中,但是会清空相关的缓存数据,以保证缓存的数据与数据库的数据一致。

  • 缓存大小限制:一级缓存的大小是有限的,默认情况下,一级缓存的大小为1024个对象。当缓存中的对象数量达到上限时,新的查询结果会导致最早的查询结果被淘汰出缓存,从而失效。

  • 手动提交事务:如果在执行查询之前手动提交了事务(调用了commit()方法),则会导致一级缓存失效。因为事务提交后,会关闭当前的SqlSession,同时清空一级缓存。

二级缓存

MyBatis二级缓存也可以被称作全局缓存,一般上是默认关闭的,并且配置方式也与一级缓存有区别,需要我们在具体的mapper映射文件中手动配置开启。

二级缓存开启的条件:
因为二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession查询的结果被缓存,伺候再次执行相同的查询语句就可以直接从缓存中获取。

  • 在核心配置文件中,设置全局配置属性cacheEnable="true",默认true,一般不需要设置
  • 在映射文件中配置<cache />
  • 二级缓存必须在SqlSession关闭或者提交后有效
  • 查询的数据所转换的实体类类型必须实现序列化的接口。

当我们开启二级缓存的时候,查询的结果会被存储在Mapper的全局缓存中,多个SqlSession可以共享同一个Mapper的二级缓存,在执行查询的时候,MyBatis会从我们的二级缓存中查询结果,如果找到则直接返回,如果没有找到,那么就会去数据库中查询,并存储到二级缓存中。

// 在Mapper接口对应的映射文件中开启二级缓存
<cache/>
  public static void main(String[] args) {try (SqlSession sqlSession = sqlSessionFactory.openSession()) {EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);// 测试二级缓存SqlSession sqlSession2 = sqlSessionFactory.openSession();EmpMapper empMapper2 = sqlSession2.getMapper(EmpMapper.class);Emp emp3 = empMapper2.getEmpById(1); // 第一次查询,会从数据库中获取数据sqlSession2.close(); // 关闭SqlSessionSqlSession sqlSession3 = sqlSessionFactory.openSession();EmpMapper empMapper3 = sqlSession3.getMapper(EmpMapper.class);Emp emp4 = empMapper3.getEmpById(1); // 第二次查询,会从二级缓存中获取数据sqlSession3.close();System.out.println(emp3 == emp4); // 输出:true,说明从二级缓存中获取到了同一个对象}}

cache标签的配置属性值

  • eviction:指定缓存的回收策略,用于决定在缓存达到上限时如何清理缓存。常用的回收策略包括:

    • LRU(Least Recently Used):最近最少使用,根据最近的访问时间来淘汰数据。
    • FIFO(First In, First Out):先进先出,根据数据最早进入缓存的时间来淘汰数据。
    • SOFT:软引用,根据JVM的垃圾回收机制来决定是否清理缓存数据。
    • WEAK:弱引用,类似于软引用,但更容易被垃圾回收器回收。
  • flushInterval:指定缓存刷新间隔,表示缓存刷新的时间间隔,单位为毫秒。设置了该属性后,缓存会定期刷新,以保证缓存数据的有效性。

  • readOnly:指定缓存是否为只读,如果设置为true,表示缓存数据不会被修改,可以提高缓存的性能。

  • size:指定缓存的大小限制,表示缓存中可以存储的对象数量上限。当缓存中的对象数量达到该上限时,会根据回收策略进行数据清理。

  • type:指定缓存的实现类型,可以是MyBatis提供的内置缓存实现,也可以是自定义的缓存实现。常用的内置缓存实现包括:

    • PERPETUAL:永久缓存,数据永久保存在缓存中。
    • FIFO:先进先出缓存。
    • LRU:最近最少使用缓存。
    • SOFT:软引用缓存。
    • WEAK:弱引用缓存。

示例配置:

<cacheeviction="LRU"flushInterval="60000"readOnly="false"size="1024"type="PERPETUAL"/>

MyBatis缓存查询顺序:

先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿出来使用,如果二级缓存没有命中,那就在查一级缓存,如果一级缓存也没有命中,那就查询数据库。SqlSession关闭后,以及缓存中的数据会写入到二级缓存中。

二级缓存失效的几种原因:

数据更新:当执行了插入、更新或删除操作时,会导致与这些操作相关的缓存数据失效。MyBatis会自动将更新操作同步到缓存中,但也会清空相关的缓存数据,以保证缓存中的数据与数据库的数据一致。

并发操作:在并发环境下,如果多个线程同时对同一条数据进行更新操作,可能会导致缓存中的数据与数据库中的数据不一致。这时需要考虑缓存的并发控制策略,以避免脏数据的产生。

查询结果不满足缓存条件:MyBatis的二级缓存对查询结果有一定的条件限制,例如查询结果的类型必须是可序列化的、不能包含动态SQL等。如果查询结果不满足这些条件,可能会导致缓存失效。

缓存大小限制:二级缓存的大小是有限的,当缓存中的对象数量达到上限时,新的查询结果会导致最早的查询结果被淘汰出缓存,从而失效。

手动清空缓存:通过调用SqlSession的clearCache()方法可以手动清空二级缓存。这样会导致之前缓存的数据被清除,下一次查询会重新从数据库中获取数据。

事务提交:如果在执行查询之前手动提交了事务(调用了commit()方法),则会导致二级缓存失效。因为事务提交后,会关闭当前的SqlSession,同时清空二级缓存。

三级缓存

三级缓存是一种跨会话级别的缓存,他通过与外部缓存系统,例如Redis,Memcached等进行实现。通过外部缓存系统的集成,进而实现多个应用实例之间的缓存共享,从而提高缓存的利用率和拓展性。

关于三级缓存,无法依靠MyBatis单独实现,因为他本事不提供直接对外缓存系统的集成,故而无法实现一个完整的三级缓存示例,然而,可以通过MyBatis的扩展插件或者自定义实现来集成外部缓存系统,例如:Redis,Memcached等。
我们采用Redis自定义实现Mybatis的三级缓存。
首先,需要引入MyBatis的扩展插件,例如MyBatis Redis Cache,它是一个MyBatis的缓存插件,可以将缓存数据存储到Redis中。

然后,需要在MyBatis的配置文件中配置该插件,指定Redis作为缓存的实现:

<configuration><settings><setting name="cacheEnabled" value="true"/></settings><typeAliases><!-- 定义需要缓存的实体类别名 --></typeAliases><environments default="development"><environment id="development"><transactionManager type="JDBC"/><dataSource type="POOLED"><!-- 配置数据源信息 --></dataSource></environment></environments><mappers><!-- 配置Mapper接口 --></mappers><plugins><plugin interceptor="org.mybatis.caches.redis.RedisCache"/></plugins>
</configuration>

<plugin>标签配置了MyBatis Redis Cache插件,将Redis作为缓存的实现。

接下来,可以在Java代码中进行测试,通过调用Mapper接口的方法来触发缓存的使用:

public class MyBatisCacheTest {public static void main(String[] args) {try (SqlSession sqlSession = sqlSessionFactory.openSession()) {EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);// 调用Mapper接口的方法进行查询Emp emp1 = empMapper.getEmpById(1); // 第一次查询,会从数据库中获取数据Emp emp2 = empMapper.getEmpById(1); // 第二次查询,会从Redis缓存中获取数据System.out.println(emp1 == emp2); // 输出:true,说明从Redis缓存中获取到了同一个对象}}
}

实际的三级缓存实现可能会更加复杂,涉及到缓存的清理、失效策略、缓存击穿和雪崩等问题,需要根据实际情况进行更加细致的配置和测试。

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

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

相关文章

rust 学习--所有权

所有权是rust的核心功能。 Rust 是通过所有权来管理内存回收的 栈&#xff08;Stack&#xff09; 栈是后进先出的 栈中存储的数据在编译时是固定内存大小的数据 数据移除栈叫出栈&#xff0c;数据存入栈叫入栈 入栈要比在堆上分配内存块&#xff0c;入栈时分配器无需为存储…

【全开源】智能名片系统源码(Fastadmin+ThinkPHP和Uniapp)

数字时代的新名片&#xff0c;连接未来的桥梁 引言 在数字化浪潮的推动下&#xff0c;传统名片已经逐渐淡出人们的视线。取而代之的是智能名片系统&#xff0c;它以其高效、便捷和智能化的特点&#xff0c;成为了商务交流的新宠。而智能名片系统源码&#xff0c;作为其核心驱…

Spring Cloud应用框架

一、引言 随着微服务架构的兴起&#xff0c;如何有效地管理和协调微服务之间的通信、配置、服务发现、熔断等成为了关键问题。Spring Cloud作为一套微服务解决方案&#xff0c;提供了丰富的组件和功能&#xff0c;帮助开发者快速构建和部署微服务应用。本文将详细介绍Spring C…

SAP销售手工发票录入

销售手工发票录入用于处理未启用 SD 模块标准处理流程的零星销售业务。 科目设置 收入类科目&#xff1a;设置税务类型&#xff0c;允许含税/不含税过账应收账款: 留空。其他应收款的设置类似 编辑选项设置 在中国&#xff0c;编辑选项一般设置为基于总额计税。使用事务码 FB…

2024 Etsy替代品:推荐探索手工艺品销售的其他平台

在寻找一个适合销售手工艺品的平台时&#xff0c;Etsy可能是许多人首先想到的选择。然而&#xff0c;除了Etsy之外&#xff0c;还有许多其他平台可以帮助手工艺品制作者推广和销售他们的作品。在本篇文章中&#xff0c;我们将探索一些Etsy的替代品&#xff0c;为您提供更多销售…

操作系统课程实验3-可变分区存储管理

操作系统课程实验3-可变分区存储管理 一、实验介绍 1.1 实验目的 加深对可变分区存储管理的理解&#xff1b;提高用C语言编制大型系统程序的能力&#xff0c;特别是掌握C语言编程的难点&#xff1a;指针和指针作为函数参数&#xff1b;掌握用指针实现链表和在链表上的基本操作…

React Native 之 图片使用(六)

静态图片资源 React Native项目中&#xff0c;图片文件的查找会和 JS 模块的查找方式一样。它提供了一个统一的方式来管理 iOS 和 Android 应用中的图片。要往 App 中添加一个静态图片&#xff0c;只需把图片文件放在代码文件夹中某处&#xff0c;然后像下面这样去引用它&…

如何设计足够可靠的分布式缓存体系,以满足大中型移动互联网系统的需要?no.31

传统 CAP 的突破 随着分布式系统的不断演进&#xff0c;会不断遇到各种问题&#xff0c;特别是当前&#xff0c;在大中型互联网系统的演进中&#xff0c;私有云、公有云并行发展且相互融合&#xff0c;互联网系统的部署早已突破单个区域&#xff0c;系统拓扑走向全国乃至全球的…

新书推荐:6.2 else if语句

本节必须掌握的知识点&#xff1a; 示例代码二十 代码分析 汇编解析 ■if语句表达形式3 if(表达式1) statement1 else if(表达式2) statement2 else if(表达式3) statement3 …… else statementN 解析&#xff1a; 如果表达式1非0&#xff0c;则执行statement1&#…

记录github小程序短视频系统的搭建过程

GitHub - lkmc2/AwesomeVideoWxApp: 《倾心短视频》微信小程序 这个项目按readme中的来可以部署成功&#xff0c;但是会发现图片、视频全是空的&#xff0c;如下图&#xff1a; 修改源代码&#xff0c;更换图片上传与保存地址 大概涉及到这些代码块&#xff0c;进行更改即可。…

什么样的数据摆渡设备,可以满足不同网间数据的安全传输需求?

数据摆渡设备是用来在不同的网络环境间安全地传输数据的硬件或软件解决方案。它们通常用于确保在具有不同安全级别的网络&#xff08;如内网和外网&#xff09;之间进行数据交换时的安全性和合规性。以下是一些常见的数据摆渡设备和方法&#xff1a; 移动介质拷贝&#xff1a;使…

生产制造边角料核算说明及ODOO演示

今天群里有伙伴提到边角料的处理问题&#xff0c;我们梳理了一下&#xff0c;在生产过程中&#xff0c;如果产生了边角料&#xff0c;核算产成品的投料成本时需要考虑边角料的价值&#xff0c;以确保成本核算的准确性。以下是注意的几点&#xff1a; 一、边角料的入账价值 在生…

OSPF路由聚合

原理概述 与RIP不同&#xff0c;OSPF不支持自动路由聚合&#xff0c;仅支持手动路由聚合。OSPF的路由聚合有两种机制&#xff1a;区域间路由聚合和外部路由聚合。区域间路由聚合必须配置在ABR路由器上&#xff0c;指的是ABR在把与自己直接相连区域&#xff08;Area&#xff09…

K8s 二进制部署---下篇(多master节点 负载均衡 高可用)

一 master02 节点部署 master01192.168.11.5kube-apiserver&#xff0c;kube-controller-manager&#xff0c;kube-scheduler&#xff0c;etcdmaster02192.168.11.12kube-apiserver&#xff0c;kube-controller-manager&#xff0c;kube-scheduler&#xff0c;etcdnode01192.1…

RHEL7及之后系统 系统服务脚本(Rocky 9.4)

目录 源码安装 准备工作 步骤1: 下载软件 步骤2: 安装apr 步骤3: 安装apr-util 步骤4: 安装Apache HTTP Server 总结步骤 后续步骤 源码安装 准备环境&#xff1a;首先&#xff0c;确保你的系统中安装了必要的编译工具和依赖库。对于C/C程序&#xff0c;这通常包括编译器&#…

网络流量监控与流量回溯分析:全面指南

目录 什么是网络流量监控&#xff1f; 网络流量监控的主要功能 什么是流量回溯分析&#xff1f; 流量回溯分析的优势 网络流量监控与流量回溯分析的结合 如何实现有效的网络流量监控与回溯分析&#xff1f; 网络流量监控与流量回溯分析的应用场景 企业网络 数据中心 …

PEI转染试剂残留检测

转染试剂是瞬时转染生产病毒载体的主要原材料之一。聚乙烯亚胺&#xff08;Polyethylenimine, PEI&#xff09;以其适用性广泛、成本低廉、操作简便、细胞毒性低、可以在多种哺乳动物细胞中达到较高的转染效率&#xff0c;适用于无血清悬浮转染环境&#xff0c;包装容量不受限制…

【Python快速上手(二十七)】- Python3 SMTP发送邮件

目录 Python快速上手&#xff08;二十七&#xff09;- Python3 SMTP发送邮件Python3 SMTP发送邮件1. SMTP 基本概念2. 使用 smtplib 发送简单邮件2.1 设置 SMTP 服务器2.2 登录到 SMTP 服务器2.3 发送邮件2.4 关闭连接 3. 构建复杂邮件3.1 构建带有 HTML 内容的邮件3.2 发送带有…

Zookeeper 面试题(六)

1. 简述Zookeeper中的脑裂问题 &#xff1f; 在分布式系统中&#xff0c;脑裂&#xff08;Split-brain&#xff09;问题是指由于网络分区或其他故障导致系统分裂成两个或多个独立的、相互之间无法通信的部分&#xff0c;每个部分都认为自己是整个系统的唯一活跃部分。在ZooKee…

一阶数字高通滤波器

本文的主要内容包含一阶高通滤波器公式的推导和数字算法的实现以及编程和仿真 1 计算公式推导 1.1.2 算法实现及仿真 利用python实现的代码如下&#xff1a; import numpy as np # from scipy.signal import butter, lfilter, freqz import matplotlib.pyplot as plt #2pifW…