首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Mybatis源码之Statement

Mybatis源码之Statement

作者头像
用户4919348
发布2019-05-10 11:05:52
6750
发布2019-05-10 11:05:52
举报
文章被收录于专栏:波波烤鸭波波烤鸭

Statement源码分析

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

int update = session.update("com.sxt.pojo.User.update", user);
  @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));方法

@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方法查看

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对象

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());方法中。

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方法执行

@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语句

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

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

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019年04月28日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Statement源码分析
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档