MyBatis 中的缓存(一级缓存、二级缓存)

MyBatis 是一款流行的持久层框架,提供了简单的 API 来处理数据库操作。在 MyBatis 中,缓存机制是提高性能的重要手段。本文将深入探讨 MyBatis 中的一级缓存和二级缓存,解释它们的工作原理、配置方法及其使用场景。

什么是缓存

缓存是一种存储机制,用于临时保存数据以便快速访问。缓存可以减少对数据库的频繁访问,从而提升应用的性能。在 MyBatis 中,缓存机制分为一级缓存和二级缓存。

一级缓存

一级缓存是 MyBatis 默认启用的缓存机制,作用范围是 SQLSession。每个 SQLSession 对象都有自己的缓存,缓存的数据只在同一个 SQLSession 中共享。

一级缓存的工作原理

当 SQLSession 执行查询操作时,MyBatis 首先会在一级缓存中查找结果。如果缓存中存在相应的数据,直接返回缓存数据;如果缓存中没有数据,才会发起数据库查询,并将结果存入缓存。

一级缓存的特点

  • 作用范围:一级缓存的作用范围是 SQLSession,在同一个 SQLSession 内有效。
  • 默认开启:MyBatis 默认开启一级缓存,不需要额外配置。
  • 缓存失效条件
  • 执行 DML 操作(INSERT、UPDATE、DELETE),会清空一级缓存。
  • 调用 clearCache() 方法,手动清空一级缓存。
  • 关闭或提交 SQLSession 时,一级缓存会被清空。

示例

public void testFirstLevelCache() {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    try {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user1 = userMapper.getUserById(1);
        System.out.println(user1);

        User user2 = userMapper.getUserById(1);
        System.out.println(user2);

        System.out.println(user1 == user2); // true
    } finally {
        sqlSession.close();
    }
}

在上述示例中,第一次查询用户时,MyBatis 会将结果存入一级缓存。第二次查询相同用户时,直接从缓存中获取结果,因此两次查询得到的对象是相同的。

二级缓存

二级缓存是 MyBatis 提供的全局缓存机制,作用范围是 Mapper 映射文件。二级缓存的数据在不同 SQLSession 之间共享,但需要手动配置和启用。

二级缓存的工作原理

当启用二级缓存后,SQLSession 在关闭时,会将一级缓存中的数据写入二级缓存。下次查询相同数据时,如果二级缓存中存在相应的数据,直接返回缓存数据;如果缓存中没有数据,才会发起数据库查询,并将结果存入二级缓存。

二级缓存的特点

  • 作用范围:二级缓存的作用范围是 Mapper 映射文件,在不同 SQLSession 之间共享。
  • 需要手动配置:二级缓存需要在 Mapper 映射文件中手动配置启用。
  • 缓存失效条件
  • 执行 DML 操作(INSERT、UPDATE、DELETE)时,相关表的二级缓存会被清空。
  • 配置缓存刷新策略(如定时刷新、容量限制等)。

配置二级缓存

  1. 在 MyBatis 全局配置文件(mybatis-config.xml)中启用二级缓存:
<settings>
    <setting name="cacheEnabled" value="true"/>
</settings>
  1. 在 Mapper 映射文件中配置二级缓存:
<cache/>
  1. 配置缓存策略(可选):
<cache eviction="LRU" flushInterval="60000" size="512" readOnly="false"/>
  • eviction:缓存淘汰策略,如 LRU(最近最少使用)、FIFO(先进先出)、SOFT(软引用)等。
  • flushInterval:刷新间隔时间(毫秒),超过该时间后,缓存会被清空。
  • size:缓存大小,指定缓存可以存储的对象数量。
  • readOnly:是否只读,设置为 true 时,缓存中的对象不允许修改。

示例

<mapper namespace="com.example.UserMapper">
    <cache/>

    <select id="getUserById" resultType="com.example.User">
        SELECT * FROM users WHERE id = #{id}
    </select>
</mapper>

在上述示例中,<cache/> 元素启用了二级缓存。当 SQLSession 关闭时,查询结果会被写入二级缓存。下次查询相同用户时,直接从二级缓存中获取结果。

使用二级缓存的注意事项

  • 合理配置缓存策略:根据应用场景,合理配置缓存淘汰策略、刷新间隔和缓存大小,以避免内存溢出和缓存命中率低的问题。
  • 数据一致性问题:在多线程或分布式环境中,缓存数据可能出现一致性问题。可以通过配置缓存刷新策略、使用分布式缓存方案(如 Redis、Memcached)等方式解决。
  • 读写性能影响:二级缓存对读操作性能有显著提升,但写操作(包括插入、更新、删除)时需要清空相关缓存,可能会影响写操作性能。

一级缓存与二级缓存的比较

  1. 作用范围:一级缓存作用于 SQLSession,二级缓存作用于 Mapper 映射文件。
  2. 默认配置:一级缓存默认启用,二级缓存需要手动配置。
  3. 共享范围:一级缓存仅在同一个 SQLSession 内共享,二级缓存在不同 SQLSession 之间共享。
  4. 缓存失效:一级缓存在执行 DML 操作或关闭 SQLSession 时失效,二级缓存在执行 DML 操作时失效,或根据配置策略失效。

总结

MyBatis 提供的一级缓存和二级缓存机制,可以显著提高数据库操作的性能。一级缓存默认启用,作用于 SQLSession;二级缓存需要手动配置,作用于 Mapper 映射文件,并在不同 SQLSession 之间共享。通过合理配置和使用缓存机制,可以有效减少数据库访问次数,提高应用的响应速度和性能。

理解和掌握 MyBatis 的缓存机制,对于优化应用性能、提升用户体验具有重要意义。在实际开发中,需要根据具体应用场景,选择合适的缓存策略,并合理配置缓存参数,以充分发挥缓存的优势。

建站托管

系统采用Java语言编程,数据库与页面服务器完全分离,在快速与稳定的同时更加安全

方式1

¥联系洽谈 / 月

  • 三加一部署
  • 美国、香港或台湾骨干机房
  • 抗攻击.服务器采用异地双备份
  • 无优7x24服务
  • 日常维护及更新

方式3

¥联系洽谈 / 月

  • 三加一部署
  • 美国、香港或台湾骨干机房
  • 抗攻击.服务器采用异地双备份
  • 无优7x24服务
  • 日常维护及更新
超值

方式4

¥联系洽谈 / 月

  • 三加一部署
  • 美国、香港或台湾骨干机房
  • 抗攻击.服务器采用异地双备份
  • 无优7x24服务
  • 日常维护及更新

软件系统研发

自主管理机房、99.99%在线率保障,无优7x24服务,为您提供尊贵服务与解决方案

中原三合一六仔平台
中原三合一六仔平台

中原三合一系统是一个信用类型六仔租用平台,支持多盘口的系统,最近我们根据在使用的客户提出需求迭代更新…