zoukankan      html  css  js  c++  java
  • 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占位符替换为参数值

  • 相关阅读:
    Java内部类详解
    Mac连接linux服务器
    mac 添加环境变量(jmeter添加至环境变量中)
    Charles使用断点修改返回或请求参数
    解决git clone速度慢的问题
    group by分组后获得每组中时间最大的那条记录
    使用Charles进行弱网测试
    http常见的状态码
    Mac使用Charles抓取ios手机APP中的https请求
    airtest使用poco方法的断言知识
  • 原文地址:https://www.cnblogs.com/warrior4236/p/13092690.html
Copyright © 2011-2022 走看看