1. Executor的生成
Executor是通过Configuration对象中newExecutor()方法生成的,其实现源码如下所示:
public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
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) { // 交由以上3种执行器代理实现
executor = new CachingExecutor(executor);
}
executor = (Executor) interceptorChain.pluginAll(executor);
return executor;
}
由源码可看出存在3种执行器,其中CachingExecutor的实现是委托其它执行器来代理实现的。Executor先通过StatementHandler的prepare()方法预编译SQL语句,然后通过ParameterHandler来设置参数,最后ResultHandler再组装查询结果返回。 注意拦截器的实现对底层产生的影响:interceptorChain.pluginAll(executor)。
2. Executor的实现
所有的执行器Executor都继承自BaseExecutor,SimpleExecutor是执行器Executor的默认实现,以selectList()方法实现说明:
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
// MappedStatement表示的是在Mapper XML中的每个SQL片段(Select|Insert|Update|Delete)所对应的内容
MappedStatement ms = configuration.getMappedStatement(statement);
// 调用执行器来执行对应的查询操作,parameter的保存是通过StrictMap来处理的,
executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
ErrorContext.instance().reset(); // 相关上下文信息的重置
}
备注:SqlSession对应的底层的执行实际上是委托Executor来实现的,当前方法也是selectOne的默认实现。
3. Executor的执行过程
其中executor.query()方法的最终执行通常是通过SimpleExecutor的doQuery()方法来实现的:
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler,
BoundSql boundSql) throws SQLException {
Configuration configuration = ms.getConfiguration();
// Executor通过StatementHandler的prepare()方法来预编译SQL语句
StatementHandler handler =
configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
// 由Statement可看出其底层是通过JDBC来实现的
Statement stmt = prepareStatement(handler, ms.getStatementLog());
// Sql的执行处理和结果的封装执行返回都在query中实现
handler.<E>query(stmt, resultHandler);
closeStatement(stmt); // 注意内存的溢出,Statement需要在finally中关闭
}
总结:SqlSession的底层实现是交由Executor来实现的,用来调度StatementHandler,ParameterHandler和ResultHandler等来处理对应SQL的执行和结果的封装返回。