mybatis源码分析——Executor的用法

 

  Executor在mybatis中主要是用来执行jdbc操作的,分为几个类型SimpleExecutor,batchExecutor,SqlSession类维护Executor,

在SqlSession需要操作数据库时,会委托给executor执行,下面通过源码分析一下:

 

看一下DefaultSqlSession类,里面维护了Executor属性,

 

 当sqlSession调用selectList方法时,会委托给executor处理,executor.query

  public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
    try {
      MappedStatement ms = configuration.getMappedStatement(statement);
      return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
    } catch (Exception e) {
      throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
    } finally {
      ErrorContext.instance().reset();
    }
  }

 

executor调用query,到baseExecutor,然后通过钩子方法,会调用doQuery,doQuery的逻辑就是jdbc操作数据库了

  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);
      stmt = prepareStatement(handler, ms.getStatementLog());
      return handler.<E>query(stmt, resultHandler);
    } finally {
      closeStatement(stmt);
    }
  }

  

看一下prepareStatement方法,首先获取连接connection,然后通过连接获取statement,然后将参数设置进去,返回statement

  private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
    Statement stmt;
    Connection connection = getConnection(statementLog);
    stmt = handler.prepare(connection);
    handler.parameterize(stmt);
    return stmt;
  }

  

看一下statementHandler的query方法,在上一步中已经将statement封装好,在这里执行execute,然后通过resultSetHandler取回结果返回

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

  

总结:

代码的整体框架很清晰,Executor的作用就是接受SqlSession的委托,然后执行jdbc的操作,当然它对于jdbc的操作又进行了封装

主要通过StatementHandler、resultSetHandler、parameterHandler三个类进行封装

statementHandler负责获取statement、参数化、执行查询

public interface StatementHandler {

  Statement prepare(Connection connection)
      throws SQLException;

  void parameterize(Statement 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;

  BoundSql getBoundSql();

  ParameterHandler getParameterHandler();

}

  

resultSetHandler负责将执行结果转换为model

parameterHandler负责将sql占位符替换为参数值

 

posted @ 2020-06-11 13:37  程序员三藏  阅读(615)  评论(0编辑  收藏  举报