Mybatis 之 Executor

DefaultSqlSession是SqlSession的实现类。我们来看一个具体的实现方法:

@Override  
public <E> List<E> 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对象里面.

DefaultSqlSession类的成员executor是在构造函数里面给他赋值的。所以我们又要回头去查看一下是在什么时候实例化了DefaultSqlSession类。

DefaultSqlSession在SqlSessionFactory的实现类DefaultSqlSessionFactory中被创建:

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();  
  }  
}  
  
private SqlSession openSessionFromConnection(ExecutorType execType, Connection connection) {  
  try {  
    boolean autoCommit;  
    try {  
      autoCommit = connection.getAutoCommit();  
    } catch (SQLException e) {  
      // Failover to true, as most poor drivers  
      // or databases won't support transactions  
      autoCommit = true;  
    }        
    final Environment environment = configuration.getEnvironment();  
    final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);  
    final Transaction tx = transactionFactory.newTransaction(connection);  
    final Executor executor = configuration.newExecutor(tx, execType);  
    return new DefaultSqlSession(configuration, executor, autoCommit);  
  } catch (Exception e) {  
    throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);  
  } finally {  
    ErrorContext.instance().reset();  
  }  
}  

从源码中我们可以看到他是通过Configuration类的newExecutor方法来得到的,代码如下:

  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 {
      executor = new SimpleExecutor(this, transaction);
    }
    if (cacheEnabled) {
      executor = new CachingExecutor(executor);
    }
    executor = (Executor) interceptorChain.pluginAll(executor);
    return executor;
  }
Executor分成两大类,一类是CacheExecutor,另一类是普通Executor。

CacheExecutor有一个重要属性delegate,它保存的是某类普通的Executor,值在构照时传入。执行数据库update操作时,它直接调用delegate的update方法,执行query方法时先尝试从cache中取值,取不到再调用delegate的查询方法,并将查询结果存入cache中。代码如下:

  @Override
  public <E> List<E> 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, parameterObject, boundSql);
        @SuppressWarnings("unchecked")
        List<E> list = (List<E>) tcm.getObject(cache, key);
        if (list == null) {
          list = delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
          tcm.putObject(cache, key, list); // issue #578 and #116
        }
        return list;
      }
    }
    return delegate.<E> query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
  }

普通类又分为:

ExecutorType.SIMPLE: 这个执行器类型不做特殊的事情。它为每个语句的执行创建一个新的预处理语句。
ExecutorType.REUSE: 这个执行器类型会复用预处理语句。
ExecutorType.BATCH: 这个执行器会批量执行所有更新语句,如果 SELECT 在它们中间执行还会标定它们是 必须的,来保证一个简单并易于理解的行为。

分别对应SimpleExecutor,ReuseExecutor,BatchExecutor,他们都继承于BaseExecutor,BatchExecutor专门用于执行批量sql操作,ReuseExecutor会重用statement执行sql操作,SimpleExecutor只是简单执行sql没有什么特别的。下面以SimpleExecutor为例:

  @Override
  public <E> List<E> 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);
      stmt = prepareStatement(handler, ms.getStatementLog());
      return handler.<E>query(stmt, resultHandler);
    } finally {
      closeStatement(stmt);
    }
  }

可以看出,Executor本质上也是个中介,具体的事情原来是StatementHandler来完成的。











  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值