一 、StatementHandler
StatementHandler完成Mybatis最核心的工作,也是Executor实现的基础;功能包括:创建statement对象,为sql语句绑定参数,执行增删改查等SQL语句、将结果映射集进行转化;
- BaseStatementHandler:所有子类的抽象父类,定义了初始化statement的操作顺序,由子类实现具体的实例化不同的statement(模板模式);
- RoutingStatementHandler:Excutor组件真正实例化的子类,使用静态代理模式,根据上下文决定创建哪个具体实体类;
- SimpleStatmentHandler :使用statement对象访问数据库,无须参数化;
- PreparedStatmentHandler :使用预编译PrepareStatement对象访问数据库;
- CallableStatmentHandler :调用存储过程。
1.1 BaseStatementHandler
BaseStatementHandler 是一个实现了 StatementHandler 接口的抽象类,它只提供了一些参数 绑定相关的方法,并没有实现操作数据库的方法。 BaseStatementHandler 中核心宇段的含义如下:
//结果处理器,对数据库返回的结果集(ResultSet)进行封装,返回用户指定的实体类型;
protected final ResultSetHandler resultSetHandler;
//sql占位符处理器,对预编译的SQL语句进行参数设置
protected final ParameterHandler parameterHandler;
//记录执行语句的executor对象
protected final Executor executor;
//sql语句对应的MappedStatement
protected final MappedStatement mappedStatement;
protected final RowBounds rowBounds;
//sql语句
protected BoundSql boundSql;
BaseStatementHandler 实现了 StatementHandler 接口中的 prepare()方法, 该方法首先调用 instantiateStatement()抽象方法初始化 java.sq I. Statement 对象 , 然后为其配置超时时间以及 fetchSize 等设置。
@Override
//使用模板模式,定义了获取Statement的步骤,其子类实现实例化Statement的具体的方式;
public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
ErrorContext.instance().sql(boundSql.getSql());
Statement statement = null;
try {
//通过不同的子类实例化不同的Statement,分为三类:simple(statment)、prepare(prepareStatement)、callable(CallableStatementHandler)
statement = instantiateStatement(connection);
//设置超时时间
setStatementTimeout(statement, transactionTimeout);
//设置数据集大小
setFetchSize(statement);
return statement;
} catch (SQLException e) {
closeStatement(statement);
throw e;
} catch (Exception e) {
closeStatement(statement);
throw new ExecutorException("Error preparing statement. Cause: " + e, e);
}
}
BaseStatementHandler 依赖两个 重要 的组件, 它们分别是 ParameterHandler 和 ResultSetHandler 。
1.2 RoutingStatementHandler
RoutingStatementHandler:Excutor组件真正实例化的子类,使用静态代理模式,根据上下文决定创建哪个具体实体类。
RoutingStatementHandler 会根据 MappedStatement 中指定的 statementType 宇段,创建对应 的 StatementHandler 接口实现。 RoutingStatementHandler 类的具体实现代码如下:
private final StatementHandler delegate;
public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
//RoutingStatementHandler最主要的功能就是根据mappedStatment的配置,生成一个对应的StatementHandler对象并赋值给delegate
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 Executo