MyBatis 一级缓存默认开启,是 session 级别。如果要禁用一级缓存,就要设置为 statement 级别,即:

<setting name="localCacheScope" value="SESSION"/>
//STATEMENT
mybatis:
  configuration:
    local-cache-scope: session  //statement 一级缓存
    cache-enabled: false  //这里是二级缓存
    

原理其实很简单,可以看 org.apache.ibatis.executor.BaseExecutor#query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler, org.apache.ibatis.cache.CacheKey, org.apache.ibatis.mapping.BoundSql) 方法(我个人猜测是之前没设计好的临时措施):

@Override
  public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
    ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
    if (closed) {
      throw new ExecutorException("Executor was closed.");
    }
    if (queryStack == 0 && ms.isFlushCacheRequired()) {
      clearLocalCache();
    }
    List<E> list;
    try {
      queryStack++;
      list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;
      if (list != null) {
        handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
      } else {
        list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
      }
    } finally {
      queryStack--;
    }
    if (queryStack == 0) {
      for (DeferredLoad deferredLoad : deferredLoads) {
        deferredLoad.load();
      }
      // issue #601
      deferredLoads.clear();
      if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
        // issue #482
        //statement级别直接clear
        clearLocalCache();
      }
    }
    return list;
  }

在网上看到还有一种可以禁用到单个 Mapper 的方式:

禁用一级缓存:mybatis没有提供一级缓存的启用、禁用开关,但在Mapper文件对应的语句中增加flushCache="true"可以达到实际禁用一级缓存的效果,一般同时还会加上useCache="false",以便关闭二级缓存

References

  • springboot+mybatis一级缓存启用/禁用问题_NongYeting的博客-CSDN博客_springboot关闭mybatis缓存

更多推荐

禁用 MyBatis 一级缓存