• 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占位符替换为参数值

  • 相关阅读:
    hdu 1042 N!
    hdu 1002 A + B Problem II
    c++大数模板
    hdu 1004 Let the Balloon Rise
    hdu 4027 Can you answer these queries?
    poj 2823 Sliding Window
    hdu 3074 Multiply game
    hdu 1394 Minimum Inversion Number
    hdu 5199 Gunner
    九度oj 1521 二叉树的镜像
  • 原文地址:https://www.cnblogs.com/warrior4236/p/13092690.html
Copyright © 2020-2023  润新知