乐趣区

关于java:MyBatis中StatementHandler

StatementHandler 负责操作 Statement 对象和数据库进行交换, 其中还会用到 ParameterHandler 和 ResultSetHandler 进行参数的赋值和后果集的映射

1.StatementHandler 中次要的办法

 Statement prepare(Connection connection)throws SQLException;
 void parameterize(Statement statement)throws SQLException;
 int update(Statement statement) throws SQLException;
 <E> List<E> query(Statement statement,ResultHandler resultHandler)throws SQLException;

prepare: 用于创立一个 Statement 实例
parametersize: 用于初始化 Statement 对象以及对 sql 的占位符进行赋值
update: 用于告诉 Statement 对象将 insert、update、delete 操作推送到数据库
query: 用于告诉 Statement 对象将 select 操作推送数据库并返回对应的查问后果

2.StatementHandler 的继承机构

StatementHandler 的两个实现类
BaseStatementHandler: 抽象类, 提供了一些公共的实现, 简化 StatementHandler 接口的实现难度
RoutingStatementHandler:StatementHandler 接口的默认实现, 依据 StatementType 获取到真正的 StatementHandler, 而后赋值给属性 delegate

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

BaseStatementHandler 的三个实现类:
SimpleStatementHandler: 解决不须要预编译的 sql, 不须要解决参数的 sql
PreparedStatementHandler: 解决须要预编译的 sql
CallableStatementHandler: 调用存储过程

 在查问和更新时才会去获取 StatementHandler 对象, 因而它是由 Executor 治理和创立的。以 SimpleExecutor 为例剖析生成 StatementHandler 和 Statement 的源码
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {    
    Statement stmt = null;    
    try {Configuration configuration = ms.getConfiguration();        
      StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);    
    // 获取 Statement 对象
     ** stmt = prepareStatement(handler, ms.getStatementLog());    **      
      return handler.<E>query(stmt, resultHandler);    
    } finally {closeStatement(stmt);    
    }    
}

获取 Statement 实例源码剖析

private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {    
  Statement stmt;    
  Connection connection = getConnection(statementLog);    
  // 获取 Statement 实例
  stmt = handler.prepare(connection, transaction.getTimeout());    
  //stmt 进行参数解决    
  //SimpleStatementHandler 中 parameterize 为空办法, 因为它只解决简略 sql, 有参数的 sql 由
  PreparedStatementHandler 解决
  handler.parameterize(stmt);    
  return stmt;    
}    
 // 调用 RoutingStatementHandler 中的办法, 本质是调用了属性 delegate 的 prepare 办法
 // 下面提到了 delegate 的赋值
  public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {return delegate.prepare(connection, transactionTimeout);    
  }    
    
 // 调用 BaseStatementHandler 中的 prepare
  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;    
    } 

//SimpleStatementHandler 提供的实现
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();    
    }    
  }
退出移动版