欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

mybatis StatementHandler

程序员文章站 2022-07-09 19:39:36
是四大神器中最重要的一个对象。主要负责:Statement,PrepareStatement,CallableStatement创建工作。同时负责:PrepareStatement,CallableStatement输送Sql的语句的占位符,使用ParameterHandler进行参数配置。操作对象的运行行为update,select等。public interface StatementHandler { //创建Statement,PrepareStatement,CallableState...

是四大神器中最重要的一个对象。
主要负责:Statement,PrepareStatement,CallableStatement创建工作。
同时负责:PrepareStatement,CallableStatement输送Sql的语句的占位符,使用ParameterHandler进行参数配置。
操作对象的运行行为update,select等。

public interface StatementHandler {
  //创建Statement,PrepareStatement,CallableStatement
  Statement prepare(Connection connection, Integer transactionTimeout)
      throws SQLException;
  //参数初始化,针对PrepareStatement,CallableStatement关联预编译Sql语句中占位符进行修改
  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();

}

StatementHandler继承关系

mybatis StatementHandler

  • BaseStatementHandler
    负责实现prepare方法
  • RoutingStatementHandler
    三种Handler使用的调度器
  • SimpleStatementHandler
    Statement对象初始化
  • PreparedStatementHandler
    预编译对象PreparedStatement进行初始化
  • CallableStatementHandler
    CallableStatement

StatementHandler核心方法

StatementHandler对象是在SqlSession对象接收到操作命令时,由Configuraion中newStatementHandler方法负责调用.

public StatementHandler newStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
    //RoutingStatementHandler,三种Handler使用的调度器。
    //根据传入的SQL语句返回SimpleStatementHandler,PreparedStatementHandler,CallableStatementHandler
    StatementHandler statementHandler = new RoutingStatementHandler(executor, mappedStatement, parameterObject, rowBounds, resultHandler, boundSql);
    statementHandler = (StatementHandler) interceptorChain.pluginAll(statementHandler);
    return statementHandler;
  }

RoutingStatementHandler调度器代码,根据MappedStatement返回某种类型的StatementHandler。
怎么判断返回那种类型的Handler:取决于sql语句,没有占位符就是SimpleStatementHandler。有占位符的出现PreparedStatementHandler。call {} CallableStatementHandler。非人为控制

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,构造方法中都调用了父类的构造方法

protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
    this.configuration = mappedStatement.getConfiguration();
    this.executor = executor;
    this.mappedStatement = mappedStatement;
    this.rowBounds = rowBounds;

    this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
    this.objectFactory = configuration.getObjectFactory();

    if (boundSql == null) { // issue #435, get the key before calculating the statement
      generateKeys(parameterObject);
      boundSql = mappedStatement.getBoundSql(parameterObject);
    }

    this.boundSql = boundSql;
    
    //参数映射器
    this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
    //结果映射器
    this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql);
  }

通过以上的调用便生成了相应的Handler,后续Statement的创建工作便会在相应的handler中完成。(在BaseStatementHandler中prepare方法中调用了instantiateStatement抽象方法,该方法由子类实现。)
prepare方法实在执行器中调用的

@Override
  public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
    ErrorContext.instance().sql(boundSql.getSql());
    Statement statement = null;
    try {
      //重点方法,该方法是个抽象的方法,实现在子类中实现
      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);
    }
  }
  abstract Statement instantiateStatement(Connection connection) throws SQLException;

SimpleStatementHandler中instantiateStatement方法的实现,调用connection.createStatement()

@Override
  protected Statement instantiateStatement(Connection connection) throws SQLException {
    if (mappedStatement.getResultSetType() != null) {
      return connection.createStatement(mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);
    } else {
      return connection.createStatement();
    }
  }

PreparedStatementHandler中instantiateStatement方法的实现,调用connection.prepareStatement()生成,

@Override
  protected Statement instantiateStatement(Connection connection) throws SQLException {
    String sql = boundSql.getSql();
    if (mappedStatement.getKeyGenerator() instanceof Jdbc3KeyGenerator) {
      String[] keyColumnNames = mappedStatement.getKeyColumns();
      if (keyColumnNames == null) {
        return connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
      } else {
        return connection.prepareStatement(sql, keyColumnNames);
      }
    } else if (mappedStatement.getResultSetType() != null) {
      return connection.prepareStatement(sql, mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);
    } else {
      return connection.prepareStatement(sql);
    }
  }

以上便完成了statement的创建。
前文提到其同时负责:PrepareStatement,CallableStatement输送Sql的语句的占位符。
使用ParameterHandler进行参数配置,方法为parameterize。其中调用了四大神器的ParameterHandler进行参数配置

public void parameterize(Statement statement) throws SQLException {
    parameterHandler.setParameters((PreparedStatement) statement);
  }

操作对象的运行行为update,query。

int update(Statement statement)
      throws SQLException;

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

在BaseStatementHandler各个子类中重写了该方法
调用了PreparedStatement ps = (PreparedStatement) statement;ps.execute();
调用了四大神器的resultSetHandler进行结果配置

@Override
  public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
    PreparedStatement ps = (PreparedStatement) statement;
    ps.execute();
    return resultSetHandler.<E> handleResultSets(ps);
  }

本文地址:https://blog.csdn.net/wsdfym/article/details/107592986