首页 > 其他分享 >11. MyBatis的一级缓存和二级缓存有什么区别?如何配置和使用二级缓存?

11. MyBatis的一级缓存和二级缓存有什么区别?如何配置和使用二级缓存?

时间:2024-09-07 14:54:58浏览次数:11  
标签:11 缓存 SqlSession 默认 查询 二级缓存 MyBatis

在 MyBatis 中,缓存机制用于减少数据库访问次数,提高应用程序性能。MyBatis 提供了两级缓存:一级缓存和二级缓存。

1. 一级缓存(Local Cache)

  • 作用范围:一级缓存作用于 SqlSession 级别。即在同一个 SqlSession 中执行相同的 SQL 查询,如果查询参数相同,MyBatis 会从缓存中直接返回结果,而不会再次查询数据库。

  • 默认开启:一级缓存是默认开启的,并且无法关闭。

  • 缓存生命周期:一级缓存的生命周期与 SqlSession 的生命周期一致。当 SqlSession 关闭后,一级缓存也随之被清空。

  • 失效条件:在 SqlSession 期间,如果执行了 INSERTUPDATEDELETE 等写操作,一级缓存将被清空,确保数据一致性。

示例

SqlSession session = sqlSessionFactory.openSession();
User user1 = session.selectOne("selectUserById", 1);
User user2 = session.selectOne("selectUserById", 1); // 第二次查询将从缓存中获取结果

在这个例子中,如果在同一个 SqlSession 中两次查询相同的 User 对象,第二次查询结果将从一级缓存中获取。

2. 二级缓存(Global Cache)

  • 作用范围:二级缓存作用于 Mapper 映射器级别。即同一个 Mapper 中执行相同的 SQL 查询,如果查询参数相同,MyBatis 会从二级缓存中直接返回结果,而不会再次查询数据库。

  • 手动配置:二级缓存默认是关闭的,需要显式配置才能开启。

  • 缓存共享:二级缓存是跨 SqlSession 的,因此不同的 SqlSession 实例可以共享同一个二级缓存。

  • 失效条件:在某个 Mapper 中执行了 INSERTUPDATEDELETE 操作,二级缓存将被清空,确保数据一致性。

示例

// 第一次查询,结果会存入二级缓存
try (SqlSession session1 = sqlSessionFactory.openSession()) {
    UserMapper mapper = session1.getMapper(UserMapper.class);
    User user1 = mapper.selectUserById(1);
}
​
// 第二次查询,不同的 SqlSession 实例,结果从二级缓存中获取
try (SqlSession session2 = sqlSessionFactory.openSession()) {
    UserMapper mapper = session2.getMapper(UserMapper.class);
    User user2 = mapper.selectUserById(1);
}

在这个例子中,即使在不同的 SqlSession 实例中,第二次查询的结果也可以从二级缓存中获取。

如何配置和使用二级缓存?

要使用 MyBatis 的二级缓存,需要进行以下配置:

1. 启用全局二级缓存

在 MyBatis 的全局配置文件(如 mybatis-config.xml)中,启用全局二级缓存支持:

<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

默认情况下,cacheEnabled 设置为 true,表示全局启用二级缓存。

2. 在 Mapper 文件中启用二级缓存

在具体的 Mapper 文件中,通过 <cache> 标签为某个映射器启用二级缓存:

<mapper namespace="com.example.mapper.UserMapper">
​
    <!-- 启用二级缓存 -->
    <cache />
​
    <!-- SQL 映射语句 -->
    <select id="selectUserById" resultType="User">
        SELECT * FROM user WHERE id = #{id}
    </select>
​
</mapper>

<cache> 标签默认配置了 LRU(Least Recently Used,最近最少使用)缓存策略、无超时清除、无缓存大小限制等默认参数。

3. 配置二级缓存的行为

你可以在 <cache> 标签中配置缓存的具体行为,如缓存策略、缓存大小、过期时间等。

常见配置选项

  • eviction:缓存回收策略,默认为 LRU(最近最少使用),其他选项包括 FIFO(先进先出)、SOFT(软引用)、WEAK(弱引用)。

  • flushInterval:缓存刷新间隔,默认情况下不会自动刷新,可以设置毫秒级的刷新间隔。

  • size:缓存的数量,默认没有限制。

  • readOnly:是否只读,默认为 false,如果设置为 true,则提高并发性能,但所有返回的对象在缓存期间不可修改。

示例配置

<cache
    eviction="FIFO"
    flushInterval="60000" <!-- 60秒刷新一次 -->
    size="512" <!-- 缓存最多保存 512 个对象 -->
    readOnly="true" <!-- 只读缓存,提升并发性能 -->
/>

4. 使用二级缓存的注意事项

  • 与事务管理的关系:二级缓存与事务紧密关联。只有在事务提交后,查询结果才会被存储到二级缓存中。如果事务未提交或回滚,则缓存不会更新。

  • 序列化:MyBatis 的二级缓存需要将缓存对象序列化,因此被缓存的对象必须实现 Serializable 接口。

  • 缓存失效:如前所述,当执行插入、更新或删除操作时,二级缓存会被清空,以确保数据一致性。

5. 二级缓存的使用示例

假设你有以下 Java 类和 Mapper 接口:

public class User implements Serializable {
    private int id;
    private String name;
    // Getters and setters
}
​
public interface UserMapper {
    User selectUserById(int id);
}

MyBatis 配置文件

<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>

UserMapper.xml

<mapper namespace="com.example.mapper.UserMapper">
    <cache />
    <select id="selectUserById" resultType="User">
        SELECT * FROM user WHERE id = #{id}
    </select>
</mapper>

在启用了二级缓存之后,第一次查询时 MyBatis 会从数据库中获取数据并存储到二级缓存中。第二次查询相同的数据时,MyBatis 会直接从二级缓存中获取结果,而不再访问数据库。

总结

  • 一级缓存:作用于 SqlSession 级别,默认开启,生命周期与 SqlSession 相同,主要用于减少同一个会话中重复查询的数据库访问。

  • 二级缓存:作用于 Mapper 级别,默认关闭,需要手动配置。二级缓存是跨 SqlSession 的缓存,适合在多个会话中共享查询结果。

通过合理配置和使用二级缓存,可以显著提高 MyBatis 应用的性能,特别是在读多写少的场景中,二级缓存能够有效减少数据库的压力,提高查询效率。

标签:11,缓存,SqlSession,默认,查询,二级缓存,MyBatis
From: https://blog.csdn.net/zhzjn/article/details/141995899

相关文章

  • 13. 说说 MyBatis 的缓存机制?
    MyBatis提供了一级缓存和二级缓存两种缓存机制,用于提高应用程序的性能,减少数据库的访问次数。缓存机制是MyBatis的一个重要特性,通过缓存可以在一定程度上减少对数据库的访问,从而提高查询性能。1.一级缓存(LocalCache)作用范围:一级缓存是MyBatis默认开启的缓存机制,作用......
  • springboot+vue+mybatis河北经贸大学勤工助学系统+PPT+论文+讲解+售后
    河北经贸大学勤工助学系统是学校中重要的一环,勤工助学是教师、学生获取信息的主要渠道。于是经过考虑之后决定开发基于JSP技术设计与实现了一款简洁、轻便的河北经贸大学勤工助学系统。本系统解决了考勤的主要问题,包括以下多个功能模块:学生、教师、教师考勤、岗位类型、岗位......
  • 【每日刷题】Day112
    【每日刷题】Day112......
  • 配置免安装版的apache-tomcat环境,jdk11版本以上。解决控制台环境配置显示成功,确打不开
    我这里下的是jdk22版,https://download.oracle.com/java/22/latest/jdk-22_windows-x64_bin.ziphttps://download.oracle.com/java/22/latest/jdk-22_windows-x64_bin.zip 解压后放在没有中文路径的地方。win+s搜env回车打开环境变量,新建一个变量名:JAVA_HOME,值:为你的jdk解压......
  • 【小白深度教程 1.11】手把手教你使用 PSMNet 估计视差和计算深度,并映射到 3D 点云(含
    【小白深度教程1.11】手把手教你使用PSMNet估计视差和计算深度,并映射到3D点云(含Python代码)1.PSMNet简介2.环境配置3.下载预训练模型4.修改推理代码5.用PSMNet估计视差6.报错解决7.映射到3D点云8.对比传统方法9.点云可视化在之前的章节......
  • rk3566 rk3588 Android11/13 给内置APP添加相关权限,无需手动同意APP权限
    现象:打开APP会跳出权限弹窗,给APP相关权限才能够使用APP。目录1、adb查看logcat2、在SystemUIService.java内给APP添加加权限3、开机自启动APP4、executeCMD函数1、adb查看logcat打开APP,logcat会打印APP包名。我这边包名是com.jhooit.endoscope2、在SystemUIService.......
  • rk3566 android11 识别WiFi/蓝牙芯片模块有误,导致WiFi、蓝牙打不开的情况
    现象:WiFi、蓝牙驱动已安装,设备树等配置都已完成,但是WiFi/蓝牙还是打不开,要排除是否是开发板识别蓝牙WiFi芯片有误的情况。目录一、WIFI芯片识别流程二、WiFi芯片识别有误1、adb命令查看加载的WIFI芯片2、WIFI芯片对应的pidvid3、查看WiFi芯片设备和ID号4、修改默认加......
  • ffmpeg(各个系统版本安装- Windows11-Mac-Linux)
    各个系统上的安装不建议使用编译安装,大佬的话可以编译安装会各种环境问题,直接使用别人安装好的就行1.Windows11上安装ffmpeg1.官网下载ffmpeg进入DownloadFFmpeg网址,点击下载windows版ffmpeg,使用别人编译好的版本即可在releasebuilds里面选择一个版本(使用release......
  • 11.jenkins调整上线的脚本实现tag方式上线
    jenkins调整上线的脚本实现tag方式上线多次打标签重新提交到gitlab远程仓库-基于multi-linestringparameter修改脚本html_deploy_tar.sh#!/usr/bin/bashDate=$(date+%F-%H-%M)web_server="192.168.111.22192.168.111.23"Name=${Date}-${git_version}code_tar(){......
  • Windows11安装Jenkins
    Windows11安装Jenkins1.下载安装JDK11从2022年6月28日发布的Jenkins2.357和2022年9月发布的LTS版本开始,Jenkins需要Java11才能使用,放弃Java8,如果用JDK1.8,那么Jenkins版本需要是2.357版本之前。JDK11下载渠道oracle官网:https://www.oracle.com/java/technol......