首页
学习
活动
专区
圈层
工具
发布

Mybatis源码之Statement

Statement源码分析

  我们还是从入口方法开始:

代码语言:javascript
复制
int update = session.update("com.sxt.pojo.User.update", user);
代码语言:javascript
复制
  @Override
  public int update(String statement, Object parameter) {
    try {
      dirty = true;
      // ms 中的statementType默认为 PREPARED
      MappedStatement ms = configuration.getMappedStatement(statement);
      // 默认的Executor是 SimpleExecutor
      return executor.update(ms, wrapCollection(parameter));
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error updating database.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

进入executor.update(ms, wrapCollection(parameter));方法

代码语言:javascript
复制
@Override
public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
  Statement stmt = null;
  try {
    Configuration configuration = ms.getConfiguration();
    // 获取Statement的处理器
    StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
    // 根据相关的处理器获取到具体的Statement对象
    stmt = prepareStatement(handler, ms.getStatementLog());
    return handler.update(stmt);
  } finally {
    closeStatement(stmt);
  }
}

进入newStatementHandler方法查看

代码语言:javascript
复制
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;
}

RoutingStatementHandler方法中我们发现根据我们之前讲的StatementType的值来生成对于的Handler.默认此处创建的是PreparedStatementHandler对象

代码语言:javascript
复制
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());
  }

}

再回到prepareStatement(handler, ms.getStatementLog());方法中。

代码语言:javascript
复制
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
  Statement stmt;
  Connection connection = getConnection(statementLog);
  // 通过Handler准备Statement对象,此处是PreparedStatementHandler
  stmt = handler.prepare(connection, transaction.getTimeout());
  handler.parameterize(stmt);
  return stmt;
}

handler.prepare方法执行

代码语言:javascript
复制
@Override
public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
  ErrorContext.instance().sql(boundSql.getSql());
  Statement statement = null;
  try {
  	// 初始化Statement对象
    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);
  }
}

三种创建的具体实现如下: Statement

PreparedStatement

CallableStatement

最后进入handler.update(stmt)方法执行sql语句

代码语言:javascript
复制
@Override
public int update(Statement statement) throws SQLException {
  PreparedStatement ps = (PreparedStatement) statement;
  // 执行sql
  ps.execute();
  // 获取影响的行数
  int rows = ps.getUpdateCount();
  Object parameterObject = boundSql.getParameterObject();
  KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
  keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
  return rows;
}

这部分内容就跟踪这么多~

举报
领券