官方文档:https://mybatis.org/mybatis-3/zh/configuration.html
因为读官方文档的配置,觉得有歧义,所以看了下源码;
结论:cachedEnable这个开关实际上控制的上创建executor(用来处理sql的)的类型,创建的executor取决于defaultExecutorType默认是SimpleExecutor这个类是没有二级缓存功能的,如果cachedEnable是true(默认),就会使用CachingExecutor对SimpleExecutor包装。CachingExecutor这个是具有二级缓存功能的。
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
// 获得执行器类型
executorType = executorType == null ? defaultExecutorType : executorType; // 使用默认
executorType = executorType == null ? ExecutorType.SIMPLE : executorType; // 使用 ExecutorType.SIMPLE
// 创建对应实现的 Executor 对象
Executor executor;
if (ExecutorType.BATCH == executorType) {
executor = new BatchExecutor(this, transaction);
} else if (ExecutorType.REUSE == executorType) {
executor = new ReuseExecutor(this, transaction);
} else {
executor = new SimpleExecutor(this, transaction);
}
// 如果开启缓存,创建 CachingExecutor 对象,进行包装
if (cacheEnabled) {
executor = new CachingExecutor(executor);
}
// 应用插件
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
所以cachedEnable=false二级缓存就被关闭了,但是cachedEnable=true仅仅是使用了CachingExecutor,不能代表使用了二级缓存,因为CachingExecutor使用了Cache对象缓存数据,只有在Mapper中配置<cache/>
标签,解析的时候才会有Cache对象,否则还是不会用到二级缓存的。
(二级坑比较多,用的人也很少)
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
throws SQLException {
Cache cache = ms.getCache();
//cache不是空才会走这里
if (cache != null) {
flushCacheIfRequired(ms);
if (ms.isUseCache() && resultHandler == null) {
ensureNoOutParams(ms, boundSql);
@SuppressWarnings("unchecked")
List<E> list = (List<E>) tcm.getObject(cache, key);
if (list == null) {
list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
tcm.putObject(cache, key, list); // issue #578 and #116
}
return list;
}
}
// 不使用缓存
return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
个人理解,如有问题欢迎指正。