在 MyBatis 的源码中,StatementHandler 是一个非常核心接口。之所以说它核心,是因
为从代码分层的角度来说,StatementHandler 是 MyBatis 源码的边界,再往下层就是 JDBC 层面的接口了。

StatementHandler 需要和 JDBC 层面的接口打交道,它要做的事情有很多。在
执行 SQL 之前,StatementHandler 需要创建合适的 Statement 对象,然后填充参数值到
Statement 对象中,最后通过 Statement 对象执行 SQL。 SQL 执行完毕,还要
去处理查询结果等。

StatementHandler 的继承体系

image.png
最下层的三种 StatementHandler实现类与三种不同的Statement进行交互,这个不难看出来。但 RoutingStatementHandler 则是一个奇怪的存在,因为JDBC中并不存在RoutingStatement。

1
2
3
4
5
6
7
8
9
10
11
12
13
// -☆- Configuration
public StatementHandler newStatementHandler(Executor executor,
MappedStatement mappedStatement,Object parameterObject,
RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
// 创建具有路由功能的 StatementHandler
StatementHandler statementHandler = new RoutingStatementHandler(
executor, mappedStatement, parameterObject, rowBounds,
resultHandler, boundSql);

// 应用插件到 StatementHandler 上
statementHandler = (StatementHandler)interceptorChain.pluginAll(statementHandler);
return statementHandler;
}

如上,newStatementHandler 方法在创建 StatementHandler 之后,还会应用插件到
StatementHandler 上。

RoutingStatementHandler

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class RoutingStatementHandler implements StatementHandler {
private final StatementHandler delegate;
public RoutingStatementHandler(Executor executor, MappedStatement ms,
Object parameter, RowBounds rowBounds, ResultHandler resultHandler,
BoundSql boundSql) {
// 根据 StatementType 创建不同的 StatementHandler
switch (ms.getStatementType()) {
case STATEMENT:
delegate = new SimpleStatementHandler(executor, ms,
parameter, rowBounds, resultHandler, boundSql);
break;
case PREPARED:
delegate = new PreparedStatementHandler(executor, ms,
parameter, rowBounds, resultHandler, boundSql);
break;
case CALLABLE:
delegate = new CallableStatementHandler(executor,
ms, parameter, rowBounds, resultHandler, boundSql);
break;
default:
throw new ExecutorException("……");
}
}
// 其他方法逻辑均由别的 StatementHandler 代理完成,就不贴代码了
}

RoutingStatementHandler 的构造方法会根据 MappedStatement 中的 statementType 变量创建不同的 StatementHandler 实现类。默认情况下,statementType 值为 PREPARED。

StatementHandler 创建完成了,后续要做到事情是创建 Statement,以及将运行时参数和 Statement 进行绑定。