<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
,可选值包括LRU
、FIFO
、SOFT
、WEAK
。 -
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>
在这个例子中,MyMapper
和 OtherMapper
共享同一个二级缓存。
原理:
-
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
共享缓存。