MyBatis 缓存机制

embedded/2024/9/25 11:47:45/

MyBatis 缓存机制详解

MyBatis 提供了一种内置的缓存机制,用来提高数据查询的效率。通过缓存,MyBatis 可以减少对数据库的访问,提升系统性能。MyBatis 缓存分为 一级缓存(Local Cache)二级缓存(Global Cache),并且可以与第三方缓存框架集成。


1. MyBatis 缓存简介

  • 一级缓存:默认开启,作用范围是会话级别,即同一个 SQLSession 中的查询结果会被缓存。每个 SQLSession 都有自己独立的一级缓存,当 SQLSession 关闭时,一级缓存将被清空。
  • 二级缓存:需要手动开启,作用范围是全局级别(Mapper 级别),不同 SQLSession 之间可以共享二级缓存。二级缓存可以减少重复的数据库访问。

MyBatis 缓存机制的基本工作原理是:

  1. 当执行查询操作时,首先检查缓存中是否存在该查询的结果。
  2. 如果存在缓存,则直接返回缓存数据。
  3. 如果缓存中不存在该查询结果,则访问数据库,并将查询结果存入缓存

2. 一级缓存

一级缓存是 MyBatis 的默认缓存机制,它不需要额外配置,默认情况下是开启的。每个 SQLSession 都会维护一个本地缓存,用来缓存该 SQLSession 中执行的查询结果。

2.1 一级缓存工作原理
  • 一级缓存的作用范围是同一个 SQLSession。在同一个 SQLSession 中,执行相同的查询,MyBatis 会从缓存中获取数据,而不会再查询数据库。
  • 当执行 insertupdatedelete 操作时,MyBatis 会清空该 SQLSession 的一级缓存,确保数据的一致性。
2.2 一级缓存示例
java">public class UserService {@Autowiredprivate SqlSession sqlSession;public void testCache() {UserMapper mapper = sqlSession.getMapper(UserMapper.class);// 第一次查询,结果会从数据库中获取User user1 = mapper.getUserById(1);// 第二次查询相同的记录,结果会从一级缓存中获取,不会再访问数据库User user2 = mapper.getUserById(1);}
}

在上述代码中,getUserById 方法被调用两次,第二次查询时 MyBatis 会从一级缓存中获取结果,而不会再访问数据库。

2.3 一级缓存失效条件

一级缓存会在以下情况下失效:

  1. SQLSession 关闭:当 SQLSession 关闭时,一级缓存也会被清空。
  2. 执行更新操作insertupdatedelete 等更新操作会清空该会话的一级缓存,确保数据一致性。
  3. 手动清空缓存:可以通过 sqlSession.clearCache() 手动清空一级缓存
java">sqlSession.clearCache();  // 手动清空一级缓存

3. 二级缓存

二级缓存是全局级别的缓存,可以在不同 SQLSession 之间共享。二级缓存的作用范围是Mapper 级别,即同一个 Mapper 中的查询可以被多个 SQLSession 共享。

3.1 二级缓存配置

二级缓存非默认开启的,需要手动开启。在 MyBatis 中启用二级缓存非常简单,只需要在 Mapper 配置文件或注解中指定开启缓存

  1. 在 Mapper XML 中启用二级缓存

在 Mapper XML 文件中,通过添加 <cache> 标签来启用二级缓存

<mapper namespace="com.example.mapper.UserMapper"><!-- 启用二级缓存 --><cache/><select id="getUserById" resultType="User">SELECT * FROM user WHERE id = #{id}</select>
</mapper>
  1. 通过注解方式启用二级缓存

如果使用注解方式配置 Mapper,可以在接口类上添加 @CacheNamespace 注解来启用二级缓存

java">import org.apache.ibatis.annotations.CacheNamespace;
import org.apache.ibatis.annotations.Mapper;@Mapper
@CacheNamespace
public interface UserMapper {@Select("SELECT * FROM user WHERE id = #{id}")User getUserById(int id);
}
3.2 二级缓存的工作原理
  • 缓存作用范围:二级缓存是 Mapper 级别的缓存,不同 SQLSession 间的查询结果可以共享。

  • 缓存存储机制:MyBatis 的二级缓存以对象的序列化方式存储。

  • 缓存失效:与一级缓存类似,当执行 insertupdatedelete 操作时,MyBatis 会清空对应的二级缓存

  • 刷新机制:可以通过 flushInterval 配置自动刷新缓存,单位是毫秒:

    <cache flushInterval="60000"/>  <!-- 60秒刷新一次缓存 -->
    
3.3 二级缓存示例
java">public class UserService {@Autowiredprivate SqlSessionFactory sqlSessionFactory;public void testCache() {// 第一个 SQLSessionSqlSession session1 = sqlSessionFactory.openSession();UserMapper mapper1 = session1.getMapper(UserMapper.class);User user1 = mapper1.getUserById(1);session1.close();  // 一级缓存失效,但查询结果会存入二级缓存// 第二个 SQLSessionSqlSession session2 = sqlSessionFactory.openSession();UserMapper mapper2 = session2.getMapper(UserMapper.class);User user2 = mapper2.getUserById(1);  // 从二级缓存中获取session2.close();}
}

在上述代码中,session1 执行查询后,结果会存入二级缓存session2 执行相同的查询时,会从二级缓存中获取数据,而不会再访问数据库。

3.4 配置二级缓存的其他参数

除了 flushInterval<cache> 标签还可以配置其他参数,例如:

  • size缓存的最大存储对象数目(默认为 1024 个对象)。

    <cache size="500"/>  <!-- 缓存最多存储500个对象 -->
    
  • readOnly:是否开启只读模式,默认值为 false。开启只读模式后,缓存中的数据无法修改,提升并发性能。

    <cache readOnly="true"/>
    
  • eviction缓存的逐出策略,可以设置为 LRU(Least Recently Used, 最近最少使用),FIFO(先进先出),SOFT(软引用),WEAK(弱引用)。默认策略是 LRU

    <cache eviction="FIFO"/>  <!-- 先进先出策略 -->
    

4. 与第三方缓存整合

MyBatis 支持与其他第三方缓存框架(如 Ehcache、Redis)集成。通过这种方式,可以进一步增强缓存的功能和性能。

4.1 Ehcache 集成

要集成 Ehcache,首先需要引入 Ehcache 依赖:

<dependency><groupId>org.mybatis.caches</groupId><artifactId>mybatis-ehcache</artifactId><version>1.1.0</version>
</dependency>

然后,在 logback.xml 中指定缓存类型为 Ehcache:

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

最后,配置 Ehcache 的 ehcache.xml

<ehcache><cache name="com.example.mapper.UserMapper"maxEntriesLocalHeap="1000"timeToIdleSeconds="3600"timeToLiveSeconds="3600"overflowToDisk="false"/>
</ehcache>

通过这样的配置,MyBatis 可以利用 Ehcache 提供的强大缓存能力来提升缓存性能和扩展性。


5. 缓存机制的注意事项

  1. 缓存一致性问题:当数据库中的数据被修改时,一级缓存和二级缓存需要确保同步更新。如果缓存不能及时清除或刷新,可能会导致缓存和数据库数据不一致的问题。MyBatis 默认会在执行 insertupdatedelete 操作时清空缓存,但在复杂场景下,可能需要手动控制缓存的刷新。
  2. 缓存的适用场景:MyBatis 的缓存适用于查询频率高、变化较少的场景。例如,用户信息、商品分类等查询频繁但数据更新较少的数据适合使用缓存。而对于频繁更新的数据,不建议使用缓存
  3. 缓存的管理:可以通过 sqlSession.clearCache() 手动清除一级缓存,通过 @CacheNamespace<cache> 标签控制二级

缓存的配置与失效策略。


6. 总结

MyBatis 提供了灵活的一级和二级缓存机制,通过这些缓存机制,可以显著提升查询性能,减少数据库的压力。一级缓存是默认开启的会话级缓存,适用于单次会话中的重复查询。而二级缓存是全局共享的缓存,适合用于查询频率高且数据变化较少的场景。

此外,MyBatis 还支持与 Ehcache、Redis 等第三方缓存框架集成,从而提供更加强大的缓存管理功能。开发者在使用缓存时,应根据实际业务需求灵活配置缓存策略,避免缓存一致性问题。


http://www.ppmy.cn/embedded/116602.html

相关文章

基于单片机的精确电压表DA-AD转换

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于51单片机&#xff0c;采用DAC0832和ADC0832检测电压&#xff0c;0到8.5V&#xff0c;设计复位电路 LED管显示实际稳压值&#xff0c;初始电压0 二、硬件资源 基于KEIL5编写C代码&#xff0c…

Mac 命令行常用操作笔记

1. 启用和禁用 Wi-Fi 打开 Wi-Fi&#xff1a; sudo networksetup -setairportpower "Wi-Fi" on 关闭 Wi-Fi&#xff1a; sudo networksetup -setairportpower "Wi-Fi" off 2. 搜索并连接 Wi-Fi 切换到 airport 工具目录&#xff1a; cd /System/Librar…

PAT甲级-1083 List Grades

题目 题目大意 学生有姓名&#xff0c;编号和分数&#xff0c;给定分数区间&#xff0c;输出在这个区间内的人名和编号。输出顺序按照分数从高到低&#xff0c;没有重复的分数。 思路 非常简单的结构体排序题&#xff0c;定义一个结构体&#xff0c;按照题目条件sort就可以了…

从 Tesla 的 TTPoE 看资源和算法

特斯拉的 ttpoe 出来有一段时间了&#xff0c;不出所料网上一如既往的一堆 pr 文&#xff0c;大多转译自 演讲 ppt 和 Replacing TCP for Low Latency Applications&#xff0c;看了不下 20 篇中文介绍&#xff0c;基本都是上面这篇文章里的内容&#xff0c;车轱辘话颠来倒去。…

MATLAB智能优化算法-学习笔记(3)——大规模邻域搜索算法求解旅行商问题【过程+代码】

一、问题描述 旅行商问题(TSP, Traveling Salesman Problem)是组合优化中的经典问题之一。给定一组城市和每对城市之间的距离,要求找到一条最短的路径,使旅行商从某个城市出发,访问每个城市一次并最终回到出发点。TSP问题广泛应用于物流配送、工厂调度、芯片制造等领域。…

mac输入法 cpu占用,解决mac使用输入法出现卡顿延迟

1、介绍 网上有各种方法&#xff0c;例如有touchbar的macbook关闭输入建议&#xff1b;定时重启“简体中文输入法”进程&#xff1b;关闭“显示器具有单独的空间” 这些方法网上都能看到&#xff0c;有些人说能解决&#xff0c;有些人说还是卡&#xff0c;我试过了问题依然存在…

通过深度学习识别情绪

通过深度学习识别情绪&#xff08;Emotion Recognition using Deep Learning&#xff09;是一项结合多模态数据的技术&#xff0c;旨在通过分析人类的面部表情、语音语调、文本内容等特征来自动识别情绪状态。情绪识别在人机交互、健康监测、教育、娱乐等领域具有广泛的应用。 …

Xilinx 使用DDS实现本振混频上下变频

文章目录 一、什么是混频&#xff1f;二、为什么要进行混频&#xff1f;三、Matlab实现混频操作四、FPGA实现混频上下变频操作4.1 例化IP4.2 仿真验证 一、什么是混频&#xff1f; 混频&#xff08;Mixing&#xff09;是信号处理中的一个核心概念&#xff0c;混频的本质是将两个…