Mybatis源码笔记(三)、Executor

闲言少叙,书接上文,上一节我们读到 session 的执行,这一节我们来看下 Executor。Executor 也是一个接口,我们来大致看一下这个接口

public interface Executor {
ResultHandler NO_RESULT_HANDLER = null;

int update(MappedStatement ms, Object parameter) throws SQLException;

<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;

<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;

<E> Cursor<E> queryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds) throws SQLException;

List<BatchResult> flushStatements() throws SQLException;

void commit(boolean required) throws SQLException;

void rollback(boolean required) throws SQLException;

CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql);

boolean isCached(MappedStatement ms, CacheKey key);

void clearLocalCache();

void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class<?> targetType);

Transaction getTransaction();

void close(boolean forceRollback);

boolean isClosed();

void setExecutorWrapper(Executor executor);
}

在前面章节的 openSession 中我们介绍了 Executor 的创建,主要包含如下三种 Executor,分别是批量 BatchExecutor、复用 ReuseExecutor、以及简单 SimpleExecutor,默认是 SimpleExecutor。

// 获取Executor
  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 都继承了抽象类 BaseExecutor

public class BatchExecutor extends BaseExecutor {
 ......
}
public class ReuseExecutor extends BaseExecutor {
 ......
}
public class SimpleExecutor extends BaseExecutor {
 ......
}

我们继续追踪到 Executor,我们看看上一节的 update 实现

public abstract class BaseExecutor implements Executor {
......
// Executor的wrapper对象,如果开启缓存,那么会创建Executor的代理CachingExecutor,
// 通过delegate.setExecutorWrapper(this)将CachingExecutor设置进来,后期的缓存操作就委托给了子类,
// 由于mybatis本身的实现问题,在分布式环境下有可能会存在脏数据问题,所以开启缓存是要注意
  protected Executor wrapper;
 ......


  @Override
  public int update(MappedStatement ms, Object parameter) throws SQLException {
    ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());
    if (closed) {
      throw new ExecutorException("Executor was closed.");
    }
    clearLocalCache();
    // 最终进入到doUpdate方法
    return doUpdate(ms, parameter);
  }

// 抽象方法,具体的继承类实现
    protected abstract int doUpdate(MappedStatement ms, Object parameter)
      throws SQLException;

}

上述代码可以看到,具体的操作其实是委托给子类进行处理的。看一下具体的实现

public class SimpleExecutor extends BaseExecutor {

  public SimpleExecutor(Configuration configuration, Transaction transaction) {
    // 调用父类构造函数
    super(configuration, transaction);
  }

  @Override
  public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
    Statement stmt = null;
    try {
    // 获取配置
      Configuration configuration = ms.getConfiguration();
    //   获取handler
      StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
      stmt = prepareStatement(handler, ms.getStatementLog());
    //   交由handler执行
      return handler.update(stmt);
    } finally {
      closeStatement(stmt);
    }
  }
  ......
}

总结:

这一节我们主要看了 Executor 极其实现,鉴于篇幅,我们选取了其中一个方法来说明,其实还是很简单的。下一节我们将看下 Statement 是如何执行的。

发表评论

邮箱地址不会被公开。 必填项已用*标注