栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Mybatis源码分析(三)Executor & 缓存

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Mybatis源码分析(三)Executor & 缓存

Executor 执行器使用
配置

 
 

使用

String resource = "mybatis-config.xml";
//将XML配置文件构建为Configuration配置类
Reader reader = Resources.getResourceAsReader(resource);
// 通过加载配置文件流构建一个SqlSessionFactory 解析xml文件
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);

Configuration configuration = sqlSessionFactory.getConfiguration();
Connection connection = configuration.getEnvironment().getDataSource().getConnection();
Transaction transaction = configuration.getEnvironment().getTransactionFactory().newTransaction(connection);


SimpleExecutor simpleExecutor = new SimpleExecutor(configuration, transaction);
//ReuseExecutor executor = new ReuseExecutor(configuration, transaction);
MappedStatement mappedStatement = configuration.getMappedStatement("com.mx.mapper.UserMapper.selectById");

List list = simpleExecutor.doQuery(mappedStatement, 1,
       RowBounds.DEFAULT, SimpleExecutor.NO_RESULT_HANDLER, mappedStatement.getBoundSql(1));
list = simpleExecutor.doQuery(mappedStatement, 1,
       RowBounds.DEFAULT, SimpleExecutor.NO_RESULT_HANDLER, mappedStatement.getBoundSql(1));

System.out.println(list.get(0));



 


Executor

baseExecutor(一级缓存)batchExecutor(批量执行器)ReUseExecutor(可重用的)SimpleExecutor简单的CacheExecutor(加入了二级缓存)

源码 DefaultSqlSession.openSession() 数据源 执行器
SqlSession session = sqlSessionFactory.openSession();

openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);

private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
      
      final Environment environment = configuration.getEnvironment();
      
      final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
      tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
      
      final Executor executor = configuration.newExecutor(tx, execType);
      
      return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
      closeTransaction(tx); // may have fetched a connection so lets call close()
      throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

创建一个sql执行器

默认 ExecutorType.SIMPLE

public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
    executorType = executorType == null ? defaultExecutorType : executorType;
    executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
    Executor executor;
    
    if (ExecutorType.BATCH == executorType) {
      executor = new BatchExecutor(this, transaction);
    } else if (ExecutorType.REUSE == executorType) {
      //可重复使用的执行器
      executor = new ReuseExecutor(this, transaction);
    } else {
      //简单的sql执行器对象
      executor = new SimpleExecutor(this, transaction);
    }
    //判断mybatis的全局配置文件是否开启缓存
    if (cacheEnabled) {
      //把当前的简单的执行器包装成一个CachingExecutor
      executor = new CachingExecutor(executor);
    }
    
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }

执行操作 User user = session.selectOne("com.mx.mapper.UserMapper.selectById", 1);

  @Override
  public  List selectList(String statement, Object parameter, RowBounds rowBounds) {
    try {
      
      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();
    }
  }

转发给执行器操作 executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER)

  @Override
  public  List query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
    
    BoundSql boundSql = ms.getBoundSql(parameterObject);
    CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
    return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }

首先二级缓存查

@Override
  public  List query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
      throws SQLException {
    
    Cache cache = ms.getCache();
    
    if (cache != null) {
      //判断是否需要刷新缓存
      flushCacheIfRequired(ms);
      if (ms.isUseCache() && resultHandler == null) {
        ensureNoOutParams(ms, boundSql);
        
        @SuppressWarnings("unchecked")
        List list = (List) 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);
  }

一级缓存delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);

PerpetualCache localCache 一级缓存

@Override
  public  List 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());
    //已经关闭,则抛出 ExecutorException 异常
    if (closed) {
      throw new ExecutorException("Executor was closed.");
    }
    // <2> 清空本地缓存,如果 queryStack 为零,并且要求清空本地缓存。
    if (queryStack == 0 && ms.isFlushCacheRequired()) {
      clearLocalCache();
    }
    List list;
    try {
      // <4.1> 从一级缓存中,获取查询结果
      queryStack++;
      list = resultHandler == null ? (List) localCache.getObject(key) : null;
      // <4.2> 获取到,则进行处理
      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
        clearLocalCache();
      }
    }
    return list;
  }

二级缓存-》一级缓存都查不到到数据库查queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql)
SimpleExecutor.doQuery

  @Override
  public  List doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
    Statement stmt = null;
    try {
      Configuration configuration = ms.getConfiguration();
      StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
      // 拿到连接和statement
      stmt = prepareStatement(handler, ms.getStatementLog());
      return handler.query(stmt, resultHandler);
    } finally {
      closeStatement(stmt);
    }
  }
转载请注明:文章转载自 www.mshxw.com
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号