你的位置:首页 > ASP.net教程

[ASP.net教程]MyBatis源码分析(二)语句处理器


StatementHandler

语句处理器,主要负责语句的创建、参数的设置、语句的执行。不负责结果集的处理。

Statement prepare(Connection connection, Integer transactionTimeout) throws SQLExceptionvoid parameterize(Statement statement) throws SQLExceptionvoid batch(Statement statement) throws SQLExceptionint update(Statement statement) throws SQLExceptionList<E> query(Statement statement, ResultHandler resultHandler) throws SQLExceptionCursor<E> queryCursor(Statement statement) throws SQLException

 

BaseStatementHandler

实现公共部分,具体差异通过抽象方法,留给子类实现。

@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);  } }protected abstract Statement instantiateStatement(Connection connection) throws SQLException;

 

首先语句级别的配置,其次配置文件中的配置。

protected void setStatementTimeout(Statement stmt, Integer transactionTimeout) throws SQLException {  Integer queryTimeout = null;  if (mappedStatement.getTimeout() != null) {   queryTimeout = mappedStatement.getTimeout();  } else if (configuration.getDefaultStatementTimeout() != null) {   queryTimeout = configuration.getDefaultStatementTimeout();  }  if (queryTimeout != null) {   stmt.setQueryTimeout(queryTimeout);  }  StatementUtil.applyTransactionTimeout(stmt, queryTimeout, transactionTimeout); }

 

首先语句级别的配置,其次配置文件中的配置。

 protected void setFetchSize(Statement stmt) throws SQLException {  Integer fetchSize = mappedStatement.getFetchSize();  if (fetchSize != null) {   stmt.setFetchSize(fetchSize);   return;  }  Integer defaultFetchSize = configuration.getDefaultFetchSize();  if (defaultFetchSize != null) {   stmt.setFetchSize(defaultFetchSize);  } }

 

StatementUtil

如果两个参数都有值,设置较小的那一个。

public static void applyTransactionTimeout(Statement statement, Integer queryTimeout, Integer transactionTimeout) throws SQLException {  if (transactionTimeout == null){   return;  }  Integer timeToLiveOfQuery = null;  if (queryTimeout == null || queryTimeout == 0) {   timeToLiveOfQuery = transactionTimeout;  } else if (transactionTimeout < queryTimeout) {   timeToLiveOfQuery = transactionTimeout;  }  if (timeToLiveOfQuery != null) {   statement.setQueryTimeout(timeToLiveOfQuery);  } }

 

SimpleStatementHandler

无参数sql语句的执行。

@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();  } } @Override public void parameterize(Statement statement) throws SQLException {  // N/A }@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 {   statement.execute(sql);   rows = statement.getUpdateCount();  }  return rows; } @Override public void batch(Statement statement) throws SQLException {  String sql = boundSql.getSql();  statement.addBatch(sql); } @Override public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {  String sql = boundSql.getSql();  statement.execute(sql);  return resultSetHandler.<E>handleResultSets(statement); } @Override public <E> Cursor<E> queryCursor(Statement statement) throws SQLException {  String sql = boundSql.getSql();  statement.execute(sql);  return resultSetHandler.<E>handleCursorResultSets(statement); }

 

PreparedStatementHandler

参数化sql语句的执行。

@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);  } } @Override public void parameterize(Statement statement) throws SQLException {  parameterHandler.setParameters((PreparedStatement) statement); }@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; } @Override public void batch(Statement statement) throws SQLException {  PreparedStatement ps = (PreparedStatement) statement;  ps.addBatch(); } @Override public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {  PreparedStatement ps = (PreparedStatement) statement;  ps.execute();  return resultSetHandler.<E> handleResultSets(ps); } @Override public <E> Cursor<E> queryCursor(Statement statement) throws SQLException {  PreparedStatement ps = (PreparedStatement) statement;  ps.execute();  return resultSetHandler.<E> handleCursorResultSets(ps); }

 

CallableStatementHandler

存储过程的执行。

@Override protected Statement instantiateStatement(Connection connection) throws SQLException {  String sql = boundSql.getSql();  if (mappedStatement.getResultSetType() != null) {   return connection.prepareCall(sql, mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);  } else {   return connection.prepareCall(sql);  } } @Override public void parameterize(Statement statement) throws SQLException {  registerOutputParameters((CallableStatement) statement);  parameterHandler.setParameters((CallableStatement) statement); }@Override public int update(Statement statement) throws SQLException {  CallableStatement cs = (CallableStatement) statement;  cs.execute();  int rows = cs.getUpdateCount();  Object parameterObject = boundSql.getParameterObject();  KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();  keyGenerator.processAfter(executor, mappedStatement, cs, parameterObject);  resultSetHandler.handleOutputParameters(cs);  return rows; } @Override public void batch(Statement statement) throws SQLException {  CallableStatement cs = (CallableStatement) statement;  cs.addBatch(); } @Override public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {  CallableStatement cs = (CallableStatement) statement;  cs.execute();  List<E> resultList = resultSetHandler.<E>handleResultSets(cs);  resultSetHandler.handleOutputParameters(cs);  return resultList; } @Override public <E> Cursor<E> queryCursor(Statement statement) throws SQLException {  CallableStatement cs = (CallableStatement) statement;  cs.execute();  Cursor<E> resultList = resultSetHandler.<E>handleCursorResultSets(cs);  resultSetHandler.handleOutputParameters(cs);  return resultList; }

 

RoutingStatementHandler

根据语句类型,自动路由到正确的语句处理器。

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