7.1 二级缓存
关于二级缓存的例子,可以查看测试中的 tk.mybatis.mapper.cache.CacheTest
。
首先需要开启二级缓存:
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 其他 -->
</configuration>
7.1.1 只使用接口
只用接口时,只需要加一个缓存的注解,示例如下:
/**
* 只有接口时,加下面的注解即可
*/
@CacheNamespace
public interface CountryCacheMapper extends Mapper<Country> {
}
对缓存的详细配置可以通过该注解提供的属性进行配置。
7.1.2 接口和 XML 混合
由于 MyBatis 目前处理 XML 和 接口中的引用时存在 BUG,所以只有这里提供的一种方式进行配置。也就是在 XML 中配置
<cache/>
,在接口中使用@CacheNamespaceRef(CountryCacheRefMapper.class)
引用注解。关于该 BUG 可以查看下面链接:
在 XML 中定义缓存:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="tk.mybatis.mapper.cache.CountryCacheRefMapper">
<cache/>
<select id="selectById" resultType="tk.mybatis.mapper.base.Country">
select * from country where id = #{id}
</select>
</mapper>
在接口中配置注解引用:
@CacheNamespaceRef(CountryCacheRefMapper.class)
//或者 @CacheNamespaceRef(name = "tk.mybatis.mapper.cache.CountryCacheRefMapper")
public interface CountryCacheRefMapper extends Mapper<Country> {
/**
* 定义在 XML 中的方法
*
* @param id
* @return
*/
Country selectById(Integer id);
}
@CacheNamespaceRef
指定的是缓存的 namespace
,就是 XML 中 <mapper>
中的 namespace
属性。
7.1.3 潜在的问题
通用 Mapper 中部分 insert, update 方法使用了 @Options
注解,在 4.0 版本中 update 方法都去掉了这个注解,但是部分 insert 必须保留。
存在
@Options
注解的方法:
tk.mybatis.mapper.common.special.InsertListMapper
int insertList(List<? extends T> recordList);
tk.mybatis.mapper.common.special.InsertUseGeneratedKeysMapper
int insertUseGeneratedKeys(T record);
tk.mybatis.mapper.common.sqlserver.InsertMapper
int insert(T record);
tk.mybatis.mapper.common.sqlserver.InsertSelectiveMapper
int insertSelective(T record);
这 4 个方法都是特殊的方法,不是
Mapper<T>
接口中包含的两个insert
方法。
MyBatis 中的 @Options
注解在 3.3.x 版本和 3.4.0+ 后的版本中,对 flushCache
方法定义不同,这就导致通用 Mapper 中无法直接配置改属性,在 3.3.x 等低版本中,该属性默认 false
,因此执行 insert
后不会清除一二级缓存。在高版本中不存在该问题。
因此如果要使用二级缓存,建议 MyBatis 使用比较新的版本,否则需要考虑使用 insert 后可能查询不到的问题。
Options
注解中的 flushCache
区别如下:
3.3.x 以及更旧的版本中:
boolean flushCache() default false;
3.4.0+中:
/**
* The options for the {@link Options#flushCache()}.
* The default is {@link FlushCachePolicy#DEFAULT}
*/
public enum FlushCachePolicy {
/** <code>false</code> for select statement; <code>true</code> for insert/update/delete statement. */
DEFAULT,
/** Flushes cache regardless of the statement type. */
TRUE,
/** Does not flush cache regardless of the statement type. */
FALSE
}
FlushCachePolicy flushCache() default FlushCachePolicy.DEFAULT;
很显然,在 3.4.0+ 中的定义更合理,所以如果使用二级缓存,建议升级到比较新的版本。