美文网首页
mybatis缓存源码解析

mybatis缓存源码解析

作者: 我是许仙 | 来源:发表于2020-06-30 18:14 被阅读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;
        }
      }
    

    相关文章

      网友评论

          本文标题:mybatis缓存源码解析

          本文链接:https://www.haomeiwen.com/subject/qxzxqktx.html