在 MyBatis 的源码中,StatementHandler 是一个非常核心接口。之所以说它核心,是因
为从代码分层的角度来说,StatementHandler 是 MyBatis 源码的边界,再往下层就是 JDBC 层面的接口了。
StatementHandler 需要和 JDBC 层面的接口打交道,它要做的事情有很多。在
执行 SQL 之前,StatementHandler 需要创建合适的 Statement 对象,然后填充参数值到
Statement 对象中,最后通过 Statement 对象执行 SQL。 SQL 执行完毕,还要
去处理查询结果等。
StatementHandler 的继承体系
最下层的三种 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 进行绑定。