mybatis二级缓存知识

时间:2024-10-18 12:27:58
<cache/>,<cache-ref/>
 @CacheNamespace,@CacheNamespaceRef

在 MyBatis 中,缓存机制能够显著提高查询效率,减少数据库的访问次数。MyBatis 提供了一级缓存(默认开启,作用范围是 SqlSession)和二级缓存(可以跨 SqlSession,需要手动开启)。在配置二级缓存时,可以使用 <cache/><cache-ref/>,以及注解形式的 @CacheNamespace@CacheNamespaceRef。下面分别解释这些概念的原理、作用和用法。

1. <cache/> 标签

作用:

<cache/> 用于开启 MyBatis 的二级缓存。它表示在对应的 Mapper 文件中为该映射器提供一个二级缓存。这个缓存可以在多个 SqlSession 之间共享,从而减少数据库查询的次数。

用法:

mapper.xml 文件中,通过简单添加 <cache/> 标签就可以为该 Mapper 开启二级缓存。这个缓存存储的是查询结果的映射,通常是通过 id 作为键。

示例:
<mapper namespace="com.example.MyMapper">
    <cache/>
    <select id="getUserById" parameterType="int" resultType="User">
        SELECT * FROM users WHERE id = #{id}
    </select>
</mapper>
原理:
  • 每个 Mapper 都可以拥有独立的二级缓存,缓存的作用范围是当前 Mapper
  • 当查询数据时,如果数据已经在缓存中,就不再查询数据库,而是直接返回缓存的数据。
  • SqlSession 关闭之后,查询的数据会被存入二级缓存中,下一次 SqlSession 执行相同查询时,可以从缓存中获取数据。
默认设置:
  • 缓存类型:PerpetualCache(永久缓存,不会自动清除)
  • 缓存策略:LRU(Least Recently Used,最近最少使用)
  • 缓存大小:默认是 1024 个对象
  • 刷新间隔:默认不设置,即不会定期刷新
  • 是否序列化:默认不序列化

你也可以自定义这些属性,例如:

<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true"/>
参数说明:
  • eviction:缓存回收策略,默认 LRU,可选值包括 LRUFIFOSOFTWEAK
  • flushInterval:缓存刷新时间,单位是毫秒。
  • size:缓存的最大对象数目。
  • readOnly:是否只读,true 表示缓存的数据是只读的,防止修改。

2. <cache-ref/> 标签

作用:

<cache-ref/> 用于引用另一个 Mapper 的二级缓存。这允许多个 Mapper 共享同一个缓存,减少重复存储数据。

用法:

mapper.xml 文件中,使用 <cache-ref/> 引用另外一个 Mapper 的缓存。

示例:
<mapper namespace="com.example.MyMapper">
    <cache-ref namespace="com.example.OtherMapper"/>
</mapper>

在这个例子中,MyMapperOtherMapper 共享同一个二级缓存。

原理:
  • cache-ref 引用了另一个 Mapper 的缓存,多个 Mapper 可以使用同一个缓存区域。
  • 数据更新时,相关的所有 Mapper 缓存都会被同步刷新。

3. @CacheNamespace 注解

作用:

@CacheNamespace 注解用于在 MyBatis 3.3 及以上版本中启用 Java 注解方式的二级缓存配置,功能等同于 <cache/> 标签。

用法:

@CacheNamespace 注解添加到 Mapper 接口上,即可为该 Mapper 开启二级缓存。

示例:
@CacheNamespace(eviction = LruCache.class, size = 512)
public interface MyMapper {
    @Select("SELECT * FROM users WHERE id = #{id}")
    User getUserById(int id);
}
原理:

<cache/> 标签的功能相同。通过 @CacheNamespace 注解,你可以在 Java 代码中配置缓存,而无需在 XML 中配置。

参数说明:
  • eviction:缓存回收策略类,如 LruCache
  • flushInterval:缓存刷新时间,单位为毫秒。
  • size:缓存的最大对象数目。
  • readWrite:是否是读写缓存,true 表示可读写。

4. @CacheNamespaceRef 注解

作用:

@CacheNamespaceRef 注解用于在 Java 注解方式中引用另一个 Mapper 的二级缓存,功能等同于 <cache-ref/> 标签。

用法:

@CacheNamespaceRef 注解添加到 Mapper 接口上,并指定要引用的缓存 namespace

示例:
@CacheNamespaceRef(MyOtherMapper.class)
public interface MyMapper {
    @Select("SELECT * FROM users WHERE id = #{id}")
    User getUserById(int id);
}
原理:

<cache-ref/> 标签相同,允许多个 Mapper 共享同一个缓存区域。


总结:

  • <cache/>@CacheNamespace 用于开启和配置二级缓存,二者可以分别在 XML 或注解中使用。
  • <cache-ref/>@CacheNamespaceRef 用于引用另一个 Mapper 的缓存,允许多个 Mapper 共享缓存。