MyBatis 学习(七)之 缓存

目录

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.mfbz.cn/a/423307.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

计算机毕业设计分享-SSM课程题库管理系统 18655(赠送源码数据库)JAVA、PHP,node.js,C++、python,大屏数据可视化等

毕业设计&#xff08;论文&#xff09; SSM课程题库管理系统 学 院 专 业 班 级 学 号 学生姓名 指导教师 完成日期…

【.Net 使用阿里云OSS 存储文件】

一、使用NuGet安装【Aliyun.OSS.SDK】 注意&#xff1a;如果有多个项目&#xff0c;需要在具体使用的项目跟启动项目都安装同一版本的Aliyun.OSS.SDK 二、上传代码 using Aliyun.OSS; using System.IO; using System; using CadApplication.Service.Dto; using System.Net; us…

QT绘图

QPainter paintEvent是Qt中一个非常重要的函数&#xff0c;它是QWidget类的一个事件处理函数&#xff0c;用于处理小部件的绘制事件。当Qt认为小部件需要重绘时&#xff08;例如&#xff0c;窗口首次出现时&#xff0c;大小改变时&#xff0c;或者调用了小部件的update()方法时…

【硬件相关】IB网/以太网基础介绍及部署实践

文章目录 一、前言1、Infiniband网络1.1、网络类型1.2、网络拓扑1.3、硬件设备1.3.1、网卡1.3.2、连接线缆a、光模块b、线缆 1.3.4、交换机 2、Ethernet网络 二、部署实践&#xff08;以太网&#xff09;1、Intel E810-XXVDA21.1、网卡信息1.2、检查命令1.2、驱动编译 2、Mella…

SQLPro Studio:数据库管理的革命性工具 mac版

SQLPro Studio是一款强大的数据库管理和开发工具&#xff0c;它旨在提供高效、便捷和安全的数据库操作体验。无论是数据库管理员、开发人员还是数据分析师&#xff0c;SQLPro Studio都能满足他们在数据库管理、查询、设计和维护方面的需求。 SQLPro Studio mac版软件获取 首先…

低密度奇偶校验码LDPC(八)——QC-LDPC译码器FPGA设计概要

往期博文 低密度奇偶校验码LDPC&#xff08;一&#xff09;——概述_什么是gallager构造-CSDN博客 低密度奇偶校验码LDPC&#xff08;二&#xff09;——LDPC编码方法-CSDN博客 低密度奇偶校验码LDPC&#xff08;三&#xff09;——QC-LDPC码概述-CSDN博客 低密度奇偶校验码…

Python环境搭建:一站式指南

在当前AIGC技术蓬勃发展的背景下&#xff0c;Python作为人工智能领域最受青睐的编程语言之一&#xff0c;成为我们必须掌握的技能。因此&#xff0c;搭建一个适合自己的Python环境成为了每个Python开发者的首要任务。本文将为您提供一站式的Python环境搭建指南&#xff0c;帮助…

JVM(5)

垃圾回收相关 垃圾收集器 警告:纯八股文! 如果说上面我们讲的收集算法是内存回收的方法论,那么垃圾收集器就是内存回收的具体体现. 垃圾收集器的作用:垃圾收集器是为了保证程序能够正常,持久运行的一种技术,它是将程序中不用的死亡对象也就是垃圾对象进行清除,从而保证新的…

Godot自定义控件样式语法解析

前言 本篇原始文章写于2023年8月7日&#xff0c;存储在我的语雀文档中。但是语雀分享有诸多不便&#xff0c;为了让更多Godoter更轻松的搜到和看到&#xff0c;就转过来了。 这个项目我上传了Github&#xff0c;后续会贴上链接。 概述 Godot控件体系存在的问题之一就是样式无…

链表OJ刷题(二)

制作不易&#xff0c;三连支持一下呗&#xff01;&#xff01;&#xff01; 文章目录 前言一、链表的回文结构二、相交链表三、链表中倒数第k个节点四、环形链表Ⅰ和Ⅱ总结 前言 一、链表的回文结构 链表的回文结构_牛客题霸_牛客网 这里我们需要先了解一下什么叫做回文&#…

Rocky Linux 运维工具 dnf

一、dnf的简介 dnf​是用于在基于RPM包管理系统的包管理工具。用户可以通过 ​yum​来搜索、安装、更新和删除软件包&#xff0c;自动处理依赖关系&#xff0c;它是yum的继任者&#xff0c;旨在提供更快速、更现代化的软件包管理体验。。 二、dnf 的参数说明 序号参数描述1in…

django项目 法律法规管理系统

1.项目结构 2.项目需求 1.用户管理模块 2.数据采集模块 3.知识管理模块 4.智能匹配模块 5.个人收藏模块 6.数据分析模块 7.页面展示模块 3.知识点 1.智能匹配模块推荐算法的实现原理 TF (Term Frequency)&#xff1a;词频&#xff0c;表示一个词在文档中出现的频…

LeetCode --- 长度最小的子数组(滑动窗口)

前言 滑动窗口算法是一种用于解决数组或者列表中子数组或者字串问题的方法&#xff0c;通常用于在给定数据上执行连续区间的操作&#xff0c;算法基本思想是维护一个固定大小或不定大小的窗口&#xff0c;通过移动窗口的起始位置和结束位置来遍历整个数据。在每个窗口位置&…

重拾前端基础知识:JavaScript

重拾前端基础知识&#xff1a;JavaScript 前言使用JavaScript输出语法运算符条件语句循环数据类型字符串数字数组对象日期函数 数学正则表达式异常处理类集合模块JSON闭包异步调试DOM&#xff08;文档对象模型&#xff09;事件事件监听器表单 BOM&#xff08;浏览器对象模型&am…

【Linux杂货铺】调试工具gdb的使用

目录 &#x1f308;前言&#x1f308; &#x1f4c1;背景介绍 &#x1f4c1; 使用 list [行号] / [函数名] run/r break/b [行号] / [函数名] info break disable break enable break delete break [断点编号] next/n step/s continue/c finish print/p [变量…

旧的Spring Security OAuth已停止维护,全面拥抱新解决方案Spring SAS

Spring Authorization Server 替换 Shiro 指引 背景 Spring 团队正式宣布 Spring Security OAuth 停止维护&#xff0c;该项目将不会再进行任何的迭代 目前 Spring 生态中的 OAuth2 授权服务器是 Spring Authorization Server 已经可以正式生产使用作为 SpringBoot 3.0 的最新…

Redis--事务机制的详解及应用

Redis事务的概念&#xff1a; Redis事务就是将一系列命令包装成一个队列&#xff0c;在执行时候按照添加的顺序依次执行&#xff0c;中间不会被打断或者干扰&#xff0c;在执行事务中&#xff0c;其他客户端提交的命令不可以插入到执行事务的队列中&#xff0c;简单来说Redis事…

Springboot接口参数校验

在设计接口时我们通常需要对接口中的非法参数做校验&#xff0c;以降低在程序运行时因为一些非法参数而导致程序发生异常的风险&#xff0c;例如登录的时候需要校验用户名密码是否为空&#xff0c;创建用户的时候需要校验邮件、手机号码格式是否准确。如果在代码中对接口参数一…

AOP案例(黑马学习笔记)

需求 需求&#xff1a;将案例中增、删、改相关接口的操作日志记录到数据库表中 ● 就是当访问部门管理和员工管理当中的增、删、改相关功能接口时&#xff0c;需要详细的操作日志&#xff0c;并保存在数据表中&#xff0c;便于后期数据追踪。 操作日志信息包含&#xff1a; ●…

基于HT32的智能家居demo(蓝牙上位机)

参加合泰杯作品的部分展示&#xff0c;基于HT32的智能家居&#xff0c;这里展示灯光的相关控制&#xff0c;是用蓝牙进行的数据透传&#xff0c;参考了一些资料&#xff0c;美化封装了一下之前的上位机界面。 成果展示 点击主界面的蓝牙设置&#xff0c;进行连接&#xff0c;下…
最新文章