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

mybatis-StatementHandler解析

程序员文章站 2022-07-05 10:52:44
概述StatementHandler,Statement处理器,主要是和jdbc中的Statement交互。public interface StatementHandler { /** * 创建Statement * @param connection * @param transactionTimeout * @return * @throws SQLException */ Statement prepare(Connection connection...

概述

StatementHandler,Statement处理器,主要是和jdbc中的Statement交互。

public interface StatementHandler {

  /**
   * 创建Statement
   * @param connection
   * @param transactionTimeout
   * @return
   * @throws SQLException
   */
  Statement prepare(Connection connection, Integer transactionTimeout)
      throws SQLException;

  /**
   * 设置参数到statement
   * @param statement
   * @throws SQLException
   */
  void parameterize(Statement statement)
      throws SQLException;

  /**
   * 批量支持
   * @param 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();

}

提供的能力:

  • 创建Statement实例
  • 设置参数
  • 执行sql

类图结构:

mybatis-StatementHandler解析
看这个结构和Executor是不是特别像。

BaseStatementHandler依旧是通用逻辑处理(异常处理、通用参数设置)

SimpleStatementHandler:普通Statement处理器。

PreparedStatementHandler:PrepareStatement处理器。

CallableStatementHandler:CallableStatement处理器。

RoutingStatementHandler:封装路由逻辑。

BaseStatementHandler

基础Statement处理器

 protected final Configuration configuration;
  /**
   * 对象工厂,用于创建返回值类型实例
   */
  protected final ObjectFactory objectFactory;
  protected final TypeHandlerRegistry typeHandlerRegistry;
  /**
   * 数据集处理器
   */
  protected final ResultSetHandler resultSetHandler;
  /**
   * 参数处理器
   */
  protected final ParameterHandler parameterHandler;
  // 执行器
  protected final Executor executor;
  // 映射Statement
  protected final MappedStatement mappedStatement;
  // 分页参数
  protected final RowBounds rowBounds;
  // 动态sql
  protected BoundSql boundSql;

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);
  }

StatementHandler 在构造函数中会创建ParameterHandler和ResultSetHandler用于参数和返回值的处理。

prepare

@Override
public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
  ErrorContext.instance().sql(boundSql.getSql());
  Statement statement = null;
  try {
    /*
     * 对应创建三种Statement,对应StatementType
     * simple
     * prepare
     * callable(用来调用存储过程)
     */
    statement = instantiateStatement(connection);

    // statement通用参数设置
    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);
  }
}

实例化Statement实例由子类实现,超时时间、fetch大小通用设置。

SimpleStatementHandler

instantiateStatement

实例化Statement,

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

通过Connection创建普通Statement。

update

 @Override
  public int update(Statement statement) throws SQLException {
    String sql = boundSql.getSql();
    Object parameterObject = boundSql.getParameterObject();
    KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
    int rows;
    
    // 主键获取处理
    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 {
      // 执行sql 返回值
      statement.execute(sql);
      rows = statement.getUpdateCount();
    }
    return rows;
  }

更新方法,增加了对主键的处理。

query

@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
  String sql = boundSql.getSql();
  statement.execute(sql);

  // 返回值处理
  return resultSetHandler.handleResultSets(statement);
}

直接执行,结果值处理交给ResultHandler。

PreparedStatementHandler

对应PrepareStatement

instantiateStatement

@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() == ResultSetType.DEFAULT) {
    return connection.prepareStatement(sql);
  } else {
    return connection.prepareStatement(sql, mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);
  }
}

其实也只是通过Connection创建PrepareStatement

update

@Override
public int update(Statement statement) throws SQLException {
  PreparedStatement ps = (PreparedStatement) statement;
  ps.execute();
  int rows = ps.getUpdateCount();
  Object parameterObject = boundSql.getParameterObject();
  KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
  keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
  return rows;
}

逻辑比较简单,执行sql后,主键生成器执行。

query

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

和Simple一样。

CallableStatementHandler(存储过程略过)

RoutingStatementHandler

路由Statement处理器

public class RoutingStatementHandler implements StatementHandler {

 
  private final StatementHandler delegate;

  public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {

    // 根据类型创建statement实例
    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());
    }

  }
  

可以看出RoutingStatementHandler其实就是在构造函数内封装了路由的逻辑,将这个switch case包装了起来,实际的实现还是委托给实际实现类完成。一个不错的小设计,可以借鉴一下。

总结

StatementHandler主要是封装了和JDBC-Statement的实例化,设置参数和返回值转换在ParameterHandler和ResultSetHandler。层层拆分,职责清晰。

本文地址:https://blog.csdn.net/qq_28695733/article/details/107198818