mybatis 二级缓存源码阅读

2020-07-02  本文已影响0人  我是许仙

mybatis 二级缓存源码阅读

二级缓存

二级缓存之所以能够跨session是因为采用的装饰器模式对Executor进行了装饰.

  1. // 配置文件中开启总开关
    <setting name="cacheEnabled" value="true" />     
    
  2. Mapper文件中开启二级缓存
    <cache eviction="LRU" flushInterval="600000" size="1024" readOnly="true"/>
    
image-20200623111635652.png
//获取一个session
SqlSession sqlSession1 = sqlSessionFactory.openSession();
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    //获取一个执行器
    final Executor executor = configuration.newExecutor(tx, execType);
    return new DefaultSqlSession(configuration, executor, autoCommit);
  }

Configuration

public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
   //设置默认的执行器
   executor = new SimpleExecutor(this, transaction);
  //判断setting标签中 cacheEnabled是否为true从而开启2级缓存总开关
  if (cacheEnabled) {
    //用了装饰器模式
    executor = new CachingExecutor(executor);
  }
  executor = (Executor) interceptorChain.pluginAll(executor);
  return executor;
}

SqlSession

这是很关键的一点,正式因为这段代码使得二级缓存跟mapper的namespace绑定

statement就是Mapper类名+方法名字

@Override
//执行select查询
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
  try {
    //获取mapper对应的 
    MappedStatement ms = configuration.getMappedStatement(statement);
    return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
  } catch (Exception e) {
    throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
  } finally {
    ErrorContext.instance().reset();
  }
}

CachingExecutor

判断对应的mapper是否开启2级缓存的地方

@Override
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
    throws SQLException {
  //判断这个ms是否设置了缓存 对应Mapper中的 <Cache/>标签
  Cache cache = ms.getCache();
  if (cache != null) {
        ...
        list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
        tcm.putObject(cache, key, list); // issue #578 and #116
      }
      return list;
    }
  }
上一篇下一篇

猜你喜欢

热点阅读