MyBatis 学习(七)之 缓存

news2024/9/29 18:48:38

目录

1 MyBatis 缓存介绍

2 一级缓存

3 二级缓存

3.1 二级缓存介绍

3.2 二级缓存配置

3.3 二级缓存测试

4 参考文档


1 MyBatis 缓存介绍

        MyBatis 缓存是 MyBatis 中的一个重要特性,用于提高数据库查询的性能。MyBatis 提供了一级缓存和二级缓存两种类型的缓存机制。

  • 一级缓存:一级缓存(本地缓存)是 MyBatis 中默认的缓存机制,它是 SqlSession 级别的缓存。当使用 SqlSession 执行一次查询时,查询到的结果集会存储在 SqlSession 的缓存中。当使用 SqlSession 再次执行相同的查询时,它会首先从缓存中获取结果,而不会再次查询数据库。一级缓存是基于事务的,当 SqlSession flush(插入、更新、修改) 或 close 后,该 SqlSession 中的所有 Cache 将被清空

  • 二级缓存:二级缓存是 Mapper 级别的缓存,也称为 namespace 级别。这意味着无论通过哪个 SqlSession 执行相同的 Mapper 接口操作,都可以访问到相同的二级缓存数据,即跨 SqlSession 共享同一 Mapper 接口的数据。二级缓存需要手动配置,它可以实现更大范围的数据共享和更高效的查询性能。二级缓存也可以配置为使用不同的缓存实现,如 Ehcache、Redis 等

        MyBatis 缓存的主要作用是减少对数据库的访问次数,提高查询性能。然而,需要注意的是,缓存也会占用内存空间,如果缓存的数据量过大,可能会导致内存溢出的问题。因此,在使用 MyBatis 缓存时,需要根据具体的应用场景和数据量进行合理的配置和调优。

2 一级缓存

        一级缓存 (local cache),即本地缓存,作用域默认为 SqlSession 。本地缓存不能被关闭,当 SqlSession flush(插入、更新、修改) 或 close 后,该 SqlSession 中的所有 Cache 将被清空。此外,也可以调用 sqlSession.clearCache() 来手动清空本地缓存。

        在 MyBatis 配置文件中可以通过设置 localCacheScope 参数来改变一级缓存的作用域,它有以下两种设置:

  • SESSION: 当设置为 SESSION 时,一级缓存将对整个 SqlSession 有效。这意味着在同一个 SqlSession 中执行的查询会共享同一个缓存。只有当执行 DML 语句(如插入、更新或删除操作)时,缓存才会被清除。这可以有效地提高相同数据多次查询的速度,但如果在多个 SqlSession 之间需要同步数据,或者有写操作发生,可能会出现脏读的情况
  • STATEMENT:当设置为 STATEMENT 时,一级缓存仅对当前执行的语句有效。这意味着每次语句执行完毕后,缓存就会被清空。这种设置适用于那些可能需要避免脏读风险的场景,因为它确保了每次查询都是独立的,不会受到其他查询的影响
@Test
public void selectById1() {
    EmployeeMapper mapper = sqlSessionOne.getMapper(EmployeeMapper.class);

    // 第一次查询
    System.out.println("第一次查询");
    Employee employee1 = mapper.selectEmployeeById(1);
    System.out.println(employee1);

    // 第二次查询
    System.out.println("第二次查询");
    Employee employee2 = mapper.selectEmployeeById(1);
    System.out.println(employee2);

    // 手动清除本地缓存
    System.out.println("清除本地缓存");
    sqlSessionOne.clearCache();

    // 第三次查询
    System.out.println("第三次查询");
    Employee employee3 = mapper.selectEmployeeById(1);
    System.out.println(employee3);

}

第一次查询,从数据库中查询数据并将查询结果保存在本地缓存中

第二次查询,直接获取本地缓存的查询结果

清空本地缓存

第三次查询,从数据库中查询数据

3 二级缓存

3.1 二级缓存介绍

        MyBatis 的二级缓存是一个更为全局的缓存机制,其作用范围是 namespace 级别,可以被多个 SqlSession 共享。它的生命周期与应用程序同步,主要用于解决一级缓存不能跨会话共享的问题。

以下是二级缓存的一些详细介绍:

  • 使用场景:二级缓存适用于多个 SqlSession 需要共享数据的场景。当开启二级缓存后,MyBatis 会先从二级缓存中获取数据,如果没有找到,则会继续查找一级缓存,最后才访问数据库
  • 配置条件:要使用二级缓存,需要满足以下条件:
    • 全局性地开启或关闭所有映射器配置文件中已配置的任何二级缓存,可以在 MyBatis 配置文件中通过设置 <setting name="cacheEnabled" value="true"> 来实现
    • 在需要使用二级缓存的映射器配置文件(如 sqlMapper.xml)中添加 <cache/> 配置
    • 使用二级缓存的实体类对象必须是可序列化的,即实现 java.io.Serializable 接口
  • 工作机制:当 SqlSession 对象关闭或提交之后,一级缓存中的数据会被写入到二级缓存当中。这样,即使在不同的 SqlSession 之间,也可以访问到相同的数据集,从而提高了数据访问的效率
  • 缓存策略:二级缓存的回收策略可以通过设置 <cache> 标签的属性来定义,例如 LRU(最近最少使用)策略,用于移除最长时间不被使用的对象

3.2 二级缓存配置

在 MyBatis 配置文件进行设置

<!--开启二级缓存-->
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

在 SQL 映射文件中设置 <cache> 标签

在 <cache> 标签中,可以设置多种属性来定义缓存的行为,例如:

  • eviction:指定缓存回收策略,默认是 LRU(最近最少使用)
    • LRU:最近最少使用:移除最长时间不被使用的对象
    • FIFO:先进先出:按对象进入缓存的顺序来移除它们
    • SOFT:软引用:移除基于垃圾回收器状态和软引用规则的对象
    • WEAK:弱引用:更积极地移除基于垃圾收集器状态和弱引用规则的对象
  • flushInterval:设置缓存刷新间隔,单位为毫秒,默认不清空
  • size:指定二级缓存可以存储的最大对象数量,默认是 1024
  • readOnly:标记缓存是否为只读,默认为 false,即可读可写,这回慢一点,但是安全
  • type:指定缓存的具体实现类型
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="true"/>

注:在 Mapper 接口使用 @CacheNamespace 注解也可以开启二级缓存

实体类实现 java.io.Serializable 接口

3.3 二级缓存测试

@Test
public void selectAll() {
    // 不同 sqlSession 对同一 mapper 接口进行操作
    SqlSession sqlSession1 = sqlSessionFactory.openSession();
    EmployeeMapper mapper1 = sqlSession1.getMapper(EmployeeMapper.class);
    SqlSession sqlSession2 = sqlSessionFactory.openSession();
    EmployeeMapper mapper2 = sqlSession2.getMapper(EmployeeMapper.class);

    // 通过 sqlSession1 进行第一次查询
    List<Employee> employees1 = mapper1.selectAllEmployee();
    for (Employee employee : employees1) {
        System.out.println(employee);
    }

    // 当 sqlsession 提交、关闭时,二级缓存会有数据
    //sqlSession1.commit();
    sqlSession1.clearCache();
    sqlSession1.close();

    // 通过 sqlSession2 进行第二次查询
    List<Employee> employees2 = mapper2.selectAllEmployee();
    for (Employee employee : employees2) {
        System.out.println(employee);
    }
}

通过 sqlSession1 进行第一次查询,二级缓存没有数据

清空 sqlSession1 的一级缓存

sqlSession1 关闭(二级缓存有查询结果,二级缓存的数据是从一级缓存中来的吗???)

通过 sqlSession2 进行第二次查询,从二级缓存中获得查询结果,二级缓存命中率 0.5

补充:

禁用二级缓存

        可以使用 useCache 属性(这个属性只有 select 有)来禁用二级缓存,默认为 true,即使用二级缓存,当然也可以通过 @Options(useCache=true) 来设置。

清空一级和二级缓存

        flushCache 属性是用来清空一级缓存和二级缓存的。select 中默认为 flushCache=false,insert、delete、update 中默认为 flushCache=true,因为执行数据的增删改 SQL 语句后,数据库与缓存数据可能已经不一致,此时缓存已经不能用了,如果不清空缓存则可能出现脏读的情况。也可以通过 @Options(flushCache=options.FlushCachePolicy.TRUE) 进行设置。

也可以通过实现 cache 接口自定义二级缓存

4 参考文档

尚硅谷文档

mybatis 中文文档 – MyBatis 3 | XML 映射器

Mybatis3详解(十二)----Mybatis缓存 - 唐浩荣 - 博客园 (cnblogs.com)

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

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

相关文章

数据结构:栈和队列的实现附上源代码(C语言版)

目录 前言 1.栈 1.1 栈的概念及结构 1.2 栈的底层数据结构选择 1.2 数据结构设计代码&#xff08;栈的实现&#xff09; 1.3 接口函数实现代码 &#xff08;1&#xff09;初始化栈 &#xff08;2&#xff09;销毁栈 &#xff08;3&#xff09;压栈 &#xff08;4&…

求最短路径之BF算法

介绍 全称Bellman-Ford算法&#xff0c;目的是求解有负权边的最短路径问题。 考虑环&#xff0c;根据环中边的边权之和的正负&#xff0c;将环分为零环、正环、负环。其中零环、正环不会影响最短路径的求解&#xff0c;而负环会影响最短路径的求解。 可用BF算法返回一个bool值…

java开发环境配置一指禅

IDEA下载与安装 IDEA 全称 IntelliJ IDEA&#xff0c;是java编程语言的集成开发环境。 idea下载地址 。 JDK安装配置 JDK是 Java 语言的软件开发工具包&#xff0c;主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心&#xff0c;它包含了JAVA的运行环…

vue项目获取拼音首字母

工具包 pinyin-pro npm install pinyin-pro 官方地址 pinyin-pro | pinyin-pro性能优异、转换准确的 js 中文转拼音工具https://pinyin-pro.cn/示例代码(获取每个汉字的拼音首字母) import {pinyin} from pinyin-pro;function getPinyinInitial(name){if (name) {let py p…

aop监控spring cloud接口超时,并记录到数据库

引入pom <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/4.0.0…

PlantUML简介

PlantUML简介 plantUML是一款开源的UML图绘制工具&#xff0c;支持通过文本来生成图形&#xff0c;使用起来非常高效。可以支持时序图、类图、对象图、活动图、思维导图等图形的绘制。你可以在IDEA中安装插件来使用PlantUML, 或者在Visual Studio Code中安装插件。 也可以在dra…

2024免费mac苹果电脑的清理和维护软件CleanMyMac X

对于 Mac 用户来说&#xff0c;电脑的清理和维护是一件让人头疼的事情。但是&#xff0c;有了 CleanMyMac X&#xff0c;这一切都将变得轻松愉快。CleanMyMac X 是一款专为 Mac 设计的电脑清理软件&#xff0c;它以其强大的功能和简单的操作&#xff0c;让无数用户为之倾倒。 C…

C语言学习DAY22

内存泄漏&#xff1a;开辟的内存空间不使用了&#xff0c;但不释放该内存空间。

AutoSAR(基础入门篇)13.3-Mcal Dio配置

目录 一、Dio port配置 二、Dio pin配置 一、Dio port配置 同之前的Port一样,双击进入Dio配置界面后会看到几乎差不多的配置界面。General和Port类似,我们不再赘述,主要讲解Dio的配置 1. 其实Dio并没有什么实质的作用,主要起到了一个重命名的功能。双击DioConfig_0进入下…

spring项目单元测试

单元测试 每个功能开发完&#xff0c;项目上线前都要做单元测试 引入依赖 AssertJ&#xff1a;断言 测试用例 编写测试用例要求&#xff1a;保证测试方法的独立性 当前测试方法不能依赖于别的测试方法&#xff0c;也不依赖于数据库中某条特定数据。 如A方法插入一条数据&a…

在网页上踢球:打造我自己的python(Django)足球网站

足球不仅仅是球场上的90分钟。它是一个不断发展的故事&#xff0c;一个全球球迷社群的粘合剂&#xff0c;一个数据和热情交织的世界。作为一名开发者和球迷&#xff0c;我决定将这两大爱好结合起来&#xff0c;用 Django 打造一个足球网站&#xff0c;让球迷们能够追踪他们最爱…

LeetCode --- 三数之和

题目描述 三数之和 代码解析 暴力 在做这一道题的时候&#xff0c;脑海里先想出来的是暴力方法&#xff0c;一次排序&#xff0c;将这个数组变为有序的&#xff0c;再通过三次for循环来寻找满足条件的数字&#xff0c;然后将符合条件的数组与之前符合条件的数组进行一一对比…

YOLOv9独家原创改进|使用HWD:Haar小波下采样模块

专栏介绍&#xff1a;YOLOv9改进系列 | 包含深度学习最新创新&#xff0c;主力高效涨点&#xff01;&#xff01;&#xff01; 一、论文简介 最大池化或跨步卷积等下采样操作在卷积神经网络&#xff08;CNNs&#xff09;中广泛使用&#xff0c;以聚合局部特征&#xff0c;扩大感…

基于springboot+vue的客户关系管理系统

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

Linux系统管理:虚拟机 Kali Linux 安装

目录 一、理论 1.Kali Linux 二、实验 1.虚拟机Kali Linux安装准备阶段 2.安装Kali Linux 2. Kali Linux 更换国内源 3. Kali Linux 设置固定IP 4. Kali Linux 开启SSH远程连接 5. MobaXterm远程连接 Kali Linux 三、问题 1.apt 命令 取代哪些 apt-get命令 一、理论…

ChatGPT支持下的PyTorch机器学习与深度学习技术应用

近年来&#xff0c;随着AlphaGo、无人驾驶汽车、医学影像智慧辅助诊疗、ImageNet竞赛等热点事件的发生&#xff0c;人工智能迎来了新一轮的发展浪潮。尤其是深度学习技术&#xff0c;在许多行业都取得了颠覆性的成果。另外&#xff0c;近年来&#xff0c;Pytorch深度学习框架受…

探索那些能唤起情感共鸣的壁纸

1、方小童在线工具集 网址&#xff1a; 方小童 该网站是一款在线工具集合的网站&#xff0c;目前包含PDF文件在线转换、随机生成美女图片、精美壁纸、电子书搜索等功能&#xff0c;喜欢的可以赶紧去试试&#xff01;

平台工程: 用Backstage构建开发者门户 - 2

本文介绍了如何使用开源Backstage构建自己的开发者门户&#xff0c;并基于此实践平台工程。本系列共两篇文章&#xff0c;这是第二篇。原文: Platform Engineering: Building Your Developer Portal with Backstage — Part 2 在本教程第一部分中我们了解了Backstage这个用于构…

Docker基础教程 - 1 Docker简介

更好的阅读体验&#xff1a;点这里 &#xff08; www.doubibiji.com &#xff09; 1 Docker简介 Docker是一个强大的容器化平台&#xff0c;让你能够更轻松地构建、部署和运行应用程序。 下面我们来学习 Docker。 1.1 Docker是什么 1 现在遇到的问题 每次部署一台服务器&…

Python学习 day07(JSON)

JSON 各种编程语言存储数据的容器不尽相同&#xff0c;在Python中有字典dict这样的数据类型&#xff0c;而其他语言可能没有对应的字典&#xff0c;为了让不同的语言都能够相互通用的传递数据&#xff0c;JSON就是一种非常良好的中转数据格式&#xff0c;如下&#xff1a; JSON…