• mybatis四大接口之 StatementHandler


    1. 继承结构

        

    1. StatementHandler:顶层接口
    2. BaseStatementHandler : 实现顶层接口的抽象类,实现了部分接口,并定义了一个抽象方法
    3. SimpleStatementHandler:对应JDBC中常用的Statement接口,用于简单SQL的处理;
    4. PreparedStatementHandler:对应JDBC中的PreparedStatement,预编译SQL的接口;
    5. CallableStatementHandler:对应JDBC中CallableStatement,用于执行存储过程相关的接口;
    6. RoutingStatementHandler:这个接口是以上三个接口的路由,没有实际操作,只是负责上面三个StatementHandler的创建及调用。

    2. BaseStatementHandler 

      三个子类都 继承 prepare() 方法,并没有重写该方法。该方法中调用了方法 instantiateStatement ();

       instantiateStatement 是一个抽象方法,根据一个Connection 返回一个Statement 对象;

      三个子类都实现了该方法,分别返回了 StatementPrepareStaement 和 CallableStatement 对象。

      @Override
      public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
        ErrorContext.instance().sql(boundSql.getSql());
        Statement statement = null;
        try {
          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);
        }
      }
    
      protected abstract Statement instantiateStatement(Connection connection) throws SQLException;

     3. 抽象类的子类实现的接口方法

      三个子类都实现了 update() ,batch() ,query()。

      在对应的方法中将传入的 Statement 对象转型为 具体的 Statement 类型进行相应的操作。

      以 PrepareStatement 示例:

      @Override
      public int update(Statement statement) throws SQLException {
        PreparedStatement ps = (PreparedStatement) statement;
        ps.execute();
        int rows = ps.getUpdateCount();
        Object parameterObject = boundSql.getParameterObject();
        KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
        keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
        return rows;
      }
    
      @Override
      public void batch(Statement statement) throws SQLException {
        PreparedStatement ps = (PreparedStatement) statement;
        ps.addBatch();
      }
    
      @Override
      public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
        PreparedStatement ps = (PreparedStatement) statement;
        ps.execute();
        return resultSetHandler.<E> handleResultSets(ps);
      }

    4. RoutingStatementHandler

      该类采用了代理模式(静态代理);

      该类直接实现了 StatmentHandler 接口,实现了接口的全部方法。

      该类持有一个 StatmentHandler  的实例,并在创建该类时根据传入的 MappedStatement 的 type 创建不同的 Statement 实例,然后通过这个具体的实例去实现相应的操作。

    public class RoutingStatementHandler implements StatementHandler {
    
      private final StatementHandler delegate;
    
      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());
        }
    
      }
    
      @Override
      public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
        return delegate.prepare(connection, transactionTimeout);
      }
    
      @Override
      public void parameterize(Statement statement) throws SQLException {
        delegate.parameterize(statement);
      }
    
      @Override
      public void batch(Statement statement) throws SQLException {
        delegate.batch(statement);
      }
    
        // 其他方法同理
        ...
    }
  • 相关阅读:
    【贪心】闭区间问题
    【贪心】电视节目安排
    中石油-高精度阶乘-java
    hdu 6444 Neko's loop 单调队列优化DP
    hdu 3415 Max Sum of Max-K-sub-sequence 单调队列优化DP
    51nod 1050 循环数组最大子段和 单调队列优化DP
    hdu 6406 Taotao Picks Apples 线段树 单点更新
    Wannafly 挑战赛22 D 整数序列 线段树 区间更新,区间查询
    dp专题训练
    zoj 3747 递推dp
  • 原文地址:https://www.cnblogs.com/virgosnail/p/10073235.html
Copyright © 2020-2023  润新知