Mybatis源码笔记(四)、StatementHandler

在上一节中我们看到,Statement 处理主要由 StatementHandler 接口实现,StatementHandler 由 configuration.newStatementHandler 创建

 StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
      stmt = prepareStatement(handler, ms.getStatementLog());
      return handler.update(stmt);


public StatementHandler newStatementHandler(Executor executor,
MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
    StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
    statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
    return statementHandler;
  }

//   根据 不同的类型创建不同的StatementHandler
    public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {

    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("Unknown statement type: " + ms.getStatementType());
    }

  }

我们看一下 StatementHandler 接口的方法

public interface StatementHandler {

Statement prepare(Connection connection, Integer transactionTimeout)
throws SQLException;

void parameterize(Statement statement)
throws SQLException;

void batch(Statement statement)
throws SQLException;

int update(Statement statement)
throws SQLException;

<E> List<E> query(Statement statement, ResultHandler resultHandler)
throws SQLException;

<E> Cursor<E> queryCursor(Statement statement)
throws SQLException;

BoundSql getBoundSql();

ParameterHandler getParameterHandler();

}

我们选取其中的 SimpleStatementHandler 来具体分析下,SimpleStatementHandler 继承了 BaseStatementHandler,BaseStatementHandler 实现了 StatementHandler 接口


public abstract class BaseStatementHandler implements StatementHandler { // 配置 protected final Configuration configuration; protected final ObjectFactory objectFactory; protected final TypeHandlerRegistry typeHandlerRegistry; //结果处理 protected final ResultSetHandler resultSetHandler; //参数处理 protected final ParameterHandler parameterHandler; // 具体的执行器 protected final Executor executor; // mappedStatement protected final MappedStatement mappedStatement; ...... } // 继承实现类SimpleStatementHandler public class SimpleStatementHandler extends BaseStatementHandler { ...... @Override public int update(Statement statement) throws SQLException { // 执行SQL String sql = boundSql.getSql(); // SQL param Object parameterObject = boundSql.getParameterObject(); // 主键生成方式 KeyGenerator keyGenerator = mappedStatement.getKeyGenerator(); int rows; // 根据不同的keyGenerator,传入 不同的参数执行,最后返回结果 if (keyGenerator instanceof Jdbc3KeyGenerator) { // 很熟悉的味道 statement.execute(sql, Statement.RETURN_GENERATED_KEYS); rows = statement.getUpdateCount(); keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject); } else if (keyGenerator instanceof SelectKeyGenerator) { statement.execute(sql); rows = statement.getUpdateCount(); keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject); } else { statement.execute(sql); rows = statement.getUpdateCount(); } // 返回结果 return rows; } ...... }

上面的 update 方法我们终于找到了熟悉的东西,JDBC 的 statement 执行,至此,一切都清楚了。其实万变不离其宗,只是框架让我们可以脱离一些低级、重复劳动,优化性能,比我们自己徒手实现的要好。但是归根结底还是基础,所以基础还是要打牢的。

发表评论

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