private int getCount(
      Connection connection,
      BoundSql boundSql,
      Configuration configuration,
      MappedStatement mappedStatement)
      throws SQLException {

    String countSql = "select count(0) from ( " + boundSql.getSql() + " )"; // 记录统计
    PreparedStatement countStmt = connection.prepareStatement(countSql);
    BoundSql countBS =
        new BoundSql(
            configuration,
            countSql,
            boundSql.getParameterMappings(),
            boundSql.getParameterObject());
    setParameters(countStmt, mappedStatement, countBS, boundSql.getParameterObject());
    ResultSet rs = countStmt.executeQuery();
    int count = 0;
    if (rs.next()) {
      count = rs.getInt(1);
    }
    rs.close();
    countStmt.close();

    return count;
  }
  @Override
  public Object intercept(Invocation invocation) throws Throwable {

    final MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];

    //        //拦截需要分页的SQL
    ////        if (mappedStatement.getId().matches(_SQL_PATTERN)) {
    //        if (StringUtils.indexOfIgnoreCase(mappedStatement.getId(), _SQL_PATTERN) != -1) {
    Object parameter = invocation.getArgs()[1];
    BoundSql boundSql = mappedStatement.getBoundSql(parameter);
    Object parameterObject = boundSql.getParameterObject();

    // 获取分页参数对象
    Page<Object> page = null;
    if (parameterObject != null) {
      page = convertParameter(parameterObject, page);
    }

    // 如果设置了分页对象,则进行分页
    if (page != null && page.getPageSize() != -1) {

      if (StringUtils.isBlank(boundSql.getSql())) {
        return null;
      }
      String originalSql = boundSql.getSql().trim();

      // 得到总记录数
      page.setCount(
          SQLHelper.getCount(originalSql, null, mappedStatement, parameterObject, boundSql, log));

      // 分页查询 本地化对象 修改数据库注意修改实现
      String pageSql = SQLHelper.generatePageSql(originalSql, page, DIALECT);
      //                if (log.isDebugEnabled()) {
      //                    log.debug("PAGE SQL:" + StringUtils.replace(pageSql, "\n", ""));
      //                }
      invocation.getArgs()[2] = new RowBounds(RowBounds.NO_ROW_OFFSET, RowBounds.NO_ROW_LIMIT);
      BoundSql newBoundSql =
          new BoundSql(
              mappedStatement.getConfiguration(),
              pageSql,
              boundSql.getParameterMappings(),
              boundSql.getParameterObject());
      // 解决MyBatis 分页foreach 参数失效 start
      if (Reflections.getFieldValue(boundSql, "metaParameters") != null) {
        MetaObject mo = (MetaObject) Reflections.getFieldValue(boundSql, "metaParameters");
        Reflections.setFieldValue(newBoundSql, "metaParameters", mo);
      }
      // 解决MyBatis 分页foreach 参数失效 end
      MappedStatement newMs =
          copyFromMappedStatement(mappedStatement, new BoundSqlSqlSource(newBoundSql));

      invocation.getArgs()[0] = newMs;
    }
    //        }
    return invocation.proceed();
  }
 private void pagination(Invocation invocation, StatementHandler target) throws SQLException {
   final MetaObject metaStatementHandler = getMetaObject(target);
   final BoundSql boundSql = target.getBoundSql();
   Page<?> page = PAGE_THREAD_LOCAL.get();
   if (page == null) {
     page = findPageParameter(boundSql.getParameterObject());
   }
   // 如果传入的参数中有分页对象且sql语句中有select,才做分页处理
   String sql = boundSql.getSql().toLowerCase();
   if (sql.startsWith("select") && page != null) {
     // 采用物理分页后,就不需要mybatis的内存分页了,所以重置下面的两个参数
     metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
     metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
     // 设置分页对象里的总记录数和总页数
     Connection connection = (Connection) invocation.getArgs()[0];
     MappedStatement mappedStatement =
         (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");
     if (page.isCountTotal()) {
       int recordsTotal = getTotalCount(sql, connection, mappedStatement, boundSql);
       page.setTotalNum(recordsTotal);
     }
     // 最后重写sql
     String pageSql = buildPageSql(sql, page);
     metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);
   }
 }
예제 #4
0
  public Object intercept(Invocation ivk) throws Throwable {
    // TODO Auto-generated method stub
    if (ivk.getTarget() instanceof RoutingStatementHandler) {
      RoutingStatementHandler statementHandler = (RoutingStatementHandler) ivk.getTarget();
      BaseStatementHandler delegate =
          (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler, "delegate");
      MappedStatement mappedStatement =
          (MappedStatement) ReflectHelper.getValueByFieldName(delegate, "mappedStatement");

      if (mappedStatement.getId().matches(pageSqlId)) { // 拦截需要分页的SQL
        BoundSql boundSql = delegate.getBoundSql();
        Object parameterObject =
            boundSql
                .getParameterObject(); // 分页SQL<select>中parameterType属性对应的实体参数,即Mapper接口中执行分页方法的参数,该参数不得为空
        if (parameterObject == null) {
          throw new NullPointerException("parameterObject尚未实例化!");
        } else {
          Connection connection = (Connection) ivk.getArgs()[0];
          String sql = boundSql.getSql();
          String countSql = "select count(0) from (" + sql + ") as tmp_count"; // 记录统计
          PreparedStatement countStmt = connection.prepareStatement(countSql);
          BoundSql countBS =
              new BoundSql(
                  mappedStatement.getConfiguration(),
                  countSql,
                  boundSql.getParameterMappings(),
                  parameterObject);
          setParameters(countStmt, mappedStatement, countBS, parameterObject);
          ResultSet rs = countStmt.executeQuery();
          int count = 0;
          if (rs.next()) {
            count = rs.getInt(1);
          }
          rs.close();
          countStmt.close();
          // System.out.println(count);
          Page page = null;
          if (parameterObject instanceof Page) { // 参数就是Page实体
            page = (Page) parameterObject;
            page.setEntityOrField(true); // 见com.ttsoft.entity.Page.entityOrField 注释
            page.setTotalResult(count);
          } else { // 参数为某个实体,该实体拥有Page属性
            Field pageField = ReflectHelper.getFieldByFieldName(parameterObject, "page");
            if (pageField != null) {
              page = (Page) ReflectHelper.getValueByFieldName(parameterObject, "page");
              if (page == null) page = new Page();
              page.setEntityOrField(false); // 见com.ttsoft.entity.Page.entityOrField 注释
              page.setTotalResult(count);
              ReflectHelper.setValueByFieldName(parameterObject, "page", page); // 通过反射,对实体对象设置分页对象
            } else {
              throw new NoSuchFieldException(parameterObject.getClass().getName() + "不存在 page 属性!");
            }
          }
          String pageSql = generatePageSql(sql, page);
          ReflectHelper.setValueByFieldName(boundSql, "sql", pageSql); // 将分页sql语句反射回BoundSql.
        }
      }
    }
    return ivk.proceed();
  }
  /**
   * 获取总页数
   *
   * @param conn
   * @param orgBoundSql
   * @param configuration
   * @param mappedStatement
   * @return
   * @throws SQLException
   */
  private int totalCount(
      Connection conn,
      BoundSql orgBoundSql,
      Configuration configuration,
      MappedStatement mappedStatement)
      throws SQLException {
    String orgSql = orgBoundSql.getSql();
    StringBuffer sqlBuffer = new StringBuffer(orgSql.length() + 100);
    sqlBuffer.append(" SELECT COUNT(0) FROM (").append(orgSql).append(") TEMP ");
    logger.debug(" this is countsql : {}", sqlBuffer.toString());
    PreparedStatement preparedStatement = conn.prepareStatement(sqlBuffer.toString());

    Object parameterObject = orgBoundSql.getParameterObject();
    BoundSql boundSql =
        new BoundSql(
            configuration,
            sqlBuffer.toString(),
            orgBoundSql.getParameterMappings(),
            parameterObject);
    setParameters(preparedStatement, mappedStatement, boundSql, parameterObject);
    ResultSet rs = preparedStatement.executeQuery();
    if (rs != null) {
      if (rs.next()) {
        return rs.getInt(1);
      }
    }
    return 0;
  }
예제 #6
0
  @Override
  public Object intercept(Invocation invocation) throws Throwable {

    // 当前环境 MappedStatement,BoundSql,及sql取得
    MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
    Object parameter = invocation.getArgs()[1];
    BoundSql boundSql = mappedStatement.getBoundSql(parameter);
    String originalSql = boundSql.getSql().trim();
    Object parameterObject = boundSql.getParameterObject();
    // Page对象获取,“信使”到达拦截器!
    Page page = searchPageWithXpath(boundSql.getParameterObject(), SystemConstant.PAGE);
    // 如果分页参数存在,进行分页处理。
    if (page != null) {
      String countSql = getCountSql(originalSql);
      Connection connection =
          mappedStatement.getConfiguration().getEnvironment().getDataSource().getConnection();
      PreparedStatement countStmt = connection.prepareStatement(countSql);
      BoundSql countBS = copyFromBoundSql(mappedStatement, boundSql, countSql);
      DefaultParameterHandler parameterHandler =
          new DefaultParameterHandler(mappedStatement, parameterObject, countBS);
      parameterHandler.setParameters(countStmt);
      ResultSet rs = countStmt.executeQuery();
      int totpage = 0;
      if (rs.next()) {
        totpage = rs.getInt(1);
      }
      rs.close();
      countStmt.close();
      connection.close();
      // 分页计算
      page.setTotalRecord(totpage);
      // 对原始Sql追加limit
      int offset = (page.getPageNo() - 1) * page.getPageSize();
      StringBuffer sb = new StringBuffer();
      sb.append(originalSql)
          .append(" limit ")
          .append(offset)
          .append(",")
          .append(page.getPageSize());
      BoundSql newBoundSql = copyFromBoundSql(mappedStatement, boundSql, sb.toString());
      MappedStatement newMs =
          copyFromMappedStatement(mappedStatement, new BoundSqlSqlSource(newBoundSql));
      invocation.getArgs()[0] = newMs;
    }
    return invocation.proceed();
  }
  /**
   * 对SQL参数(?)设值
   *
   * @param ps
   * @param mappedStatement
   * @param boundSql
   * @param parameterObject
   * @throws SQLException
   */
  private void setParameters(
      PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql)
      throws SQLException {

    ParameterHandler parameterHandler =
        mappedStatement
            .getConfiguration()
            .newParameterHandler(mappedStatement, boundSql.getParameterObject(), boundSql);
    parameterHandler.setParameters(ps);
  }
  /**
   * 获取总记录数
   *
   * @param sql 原始sql语句
   * @param conn
   * @param ms
   * @param boundSql
   * @return
   * @throws SQLException
   */
  private int getTotalCount(String sql, Connection conn, MappedStatement ms, BoundSql boundSql)
      throws SQLException {
    int start = sql.indexOf("from");
    if (start == -1) {
      throw new RuntimeException("statement has no 'from' keyword");
    }
    int stop = sql.indexOf("order by");
    if (stop == -1) {
      stop = sql.length();
    }

    String countSql = "select count(0) " + sql.substring(start, stop);
    BoundSql countBoundSql =
        new BoundSql(
            ms.getConfiguration(),
            countSql,
            boundSql.getParameterMappings(),
            boundSql.getParameterObject());
    ParameterHandler parameterHandler =
        new DefaultParameterHandler(ms, boundSql.getParameterObject(), countBoundSql);
    PreparedStatement stmt = null;
    ResultSet rs = null;
    int count = 0;
    try {
      stmt = conn.prepareStatement(countSql);
      // 通过parameterHandler给PreparedStatement对象设置参数
      parameterHandler.setParameters(stmt);
      rs = stmt.executeQuery();
      if (rs.next()) {
        count = rs.getInt(1);
      }
    } finally {
      CloseableUtil.closeQuietly(rs);
      CloseableUtil.closeQuietly(stmt);
    }
    return count;
  }
예제 #9
0
 /** 复制BoundSql对象 */
 private BoundSql copyFromBoundSql(MappedStatement ms, BoundSql boundSql, String sql) {
   BoundSql newBoundSql =
       new BoundSql(
           ms.getConfiguration(),
           sql,
           boundSql.getParameterMappings(),
           boundSql.getParameterObject());
   for (ParameterMapping mapping : boundSql.getParameterMappings()) {
     String prop = mapping.getProperty();
     if (boundSql.hasAdditionalParameter(prop)) {
       newBoundSql.setAdditionalParameter(prop, boundSql.getAdditionalParameter(prop));
     }
   }
   return newBoundSql;
 }
예제 #10
0
 @Override
 public Object intercept(Invocation invocation) throws Throwable {
   StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
   MetaObject metaStatementHandler =
       MetaObject.forObject(
           statementHandler,
           DEFAULT_OBJECT_FACTORY,
           DEFAULT_OBJECT_WRAPPER_FACTORY,
           DEFAULT_REFLECTOR_FACTORY);
   // 分离代理对象链(由于目标类可能被多个拦截器拦截,从而形成多次代理,通过下面的两次循环
   // 可以分离出最原始的的目标类)
   while (metaStatementHandler.hasGetter("h")) {
     Object object = metaStatementHandler.getValue("h");
     metaStatementHandler =
         MetaObject.forObject(
             object,
             DEFAULT_OBJECT_FACTORY,
             DEFAULT_OBJECT_WRAPPER_FACTORY,
             DEFAULT_REFLECTOR_FACTORY);
   }
   // 分离最后一个代理对象的目标类
   while (metaStatementHandler.hasGetter("target")) {
     Object object = metaStatementHandler.getValue("target");
     metaStatementHandler =
         MetaObject.forObject(
             object,
             DEFAULT_OBJECT_FACTORY,
             DEFAULT_OBJECT_WRAPPER_FACTORY,
             DEFAULT_REFLECTOR_FACTORY);
   }
   if (null == dialect || "".equals(dialect)) {
     logger.warn("Property dialect is not setted,use default 'mysql' ");
     dialect = defaultDialect;
   }
   if (null == pageSqlId || "".equals(pageSqlId)) {
     logger.warn("Property pageSqlId is not setted,use default '.*Page$' ");
     pageSqlId = defaultPageSqlId;
   }
   MappedStatement mappedStatement =
       (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement");
   PageParameter page = null;
   Object type = metaStatementHandler.getValue("delegate.boundSql.parameterObject");
   if (PageParameter.class.isInstance(type)) {
     page = (PageParameter) type;
   }
   // 只重写需要分页的sql语句。通过MappedStatement的ID匹配,默认重写以Page结尾的
   // MappedStatement的sql
   if (mappedStatement.getId().matches(pageSqlId) && page != null && page.getLimit() > 0) {
     BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql");
     Object parameterObject = boundSql.getParameterObject();
     if (parameterObject == null) {
       throw new NullPointerException("parameterObject is null!");
     } else {
       // 分页参数作为参数对象parameterObject的一个属性
       String sql = boundSql.getSql();
       // 重写sql
       String pageSql = buildPageSql(sql, page, dialect);
       metaStatementHandler.setValue("delegate.boundSql.sql", pageSql);
       // 采用物理分页后,就不需要mybatis的内存分页了,所以重置下面的两个参数
       metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
       metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
       Connection connection = (Connection) invocation.getArgs()[0];
       // 重设分页参数里的总页数等
       setPageParameter(sql, connection, mappedStatement, boundSql, page);
     }
   }
   // 将执行权交给下一个拦截器
   return invocation.proceed();
 }
예제 #11
0
  public Object intercept(Invocation ivk) throws Throwable {
    if (ivk.getTarget() instanceof RoutingStatementHandler) {
      RoutingStatementHandler statementHandler = (RoutingStatementHandler) ivk.getTarget();
      BaseStatementHandler delegate =
          (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler, "delegate");
      MappedStatement mappedStatement =
          (MappedStatement) ReflectHelper.getValueByFieldName(delegate, "mappedStatement");

      if (mappedStatement.getId().matches(pageSqlId)) { // 拦截需要分页的SQL
        BoundSql boundSql = delegate.getBoundSql();
        Object parameterObject =
            boundSql
                .getParameterObject(); // 分页SQL<select>中parameterType属性对应的实体参数,即Mapper接口中执行分页方法的参数,该参数不得为空
        if (parameterObject == null) {
          throw new NullPointerException("parameterObject尚未实例化!");
        } else {
          long count = 0;
          String sql = "";
          try {
            Connection connection = (Connection) ivk.getArgs()[0];
            sql = boundSql.getSql();
            String countSql = "";
            if ("mysql".equals(dialect)) {
              countSql = "select count(1) from (" + sql + ") as tmp_count"; // 记录统计
            } else if ("oracle".equals(dialect)) {
              countSql = "select count(1) from (" + sql + ") tmp_count"; // 记录统计
            }

            PreparedStatement countStmt = connection.prepareStatement(countSql);
            BoundSql countBS =
                new BoundSql(
                    mappedStatement.getConfiguration(),
                    countSql,
                    boundSql.getParameterMappings(),
                    parameterObject);
            setParameters(countStmt, mappedStatement, countBS, parameterObject);
            ResultSet rs = countStmt.executeQuery();

            if (rs.next()) {
              count = rs.getLong(1);
            }
            rs.close();
            countStmt.close();
          } catch (Exception e) {
            throw new RuntimeException("分页查询无法获取总记录数", e);
          }

          Pagination page = null;
          if (parameterObject instanceof Pagination) { // 参数就是Pagination实体
            page = (Pagination) parameterObject;
            page.setTotalRows(count);
          } else { // 参数为某个实体,该实体拥有Page属性
            Field pageField = ReflectHelper.getFieldByFieldName(parameterObject, "pagination");
            if (pageField != null) {
              page = (Pagination) ReflectHelper.getValueByFieldName(parameterObject, "pagination");
              if (page == null) page = new Pagination();
              page.setTotalRows(count);
              ReflectHelper.setValueByFieldName(
                  parameterObject, "pagination", page); // 通过反射,对实体对象设置分页对象
            } else {
              throw new NoSuchFieldException(
                  parameterObject.getClass().getName() + "不存在 pagination 属性!");
            }
          }
          String pageSql = generatePageSql(sql, page);
          ReflectHelper.setValueByFieldName(boundSql, "sql", pageSql); // 将分页sql语句反射回BoundSql.
        }
      }
    }
    return ivk.proceed();
  }
  @Override
  @SuppressWarnings({"unchecked", "rawtypes"})
  public Object intercept(Invocation invocation) throws Throwable {
    if (invocation.getTarget() instanceof StatementHandler) { // 控制SQL和查询总数的地方
      Page page = pageThreadLocal.get();
      Order order = orderThreadLocal.get();
      RoutingStatementHandler handler = (RoutingStatementHandler) invocation.getTarget();
      StatementHandler delegate = (StatementHandler) ReflectUtil.getFieldValue(handler, "delegate");
      BoundSql boundSql = delegate.getBoundSql();
      if (page == null) { // 不是分页查询
        if (order != null) {
          String orderSql = buildOrderSql(order, boundSql.getSql());
          ReflectUtil.setFieldValue(boundSql, "sql", orderSql);
        }
        return invocation.proceed();
      }

      Connection connection = (Connection) invocation.getArgs()[0];
      prepareAndCheckDatabaseType(connection); // 准备数据库类型

      if (page.getTotalPage() > -1) {
        if (log.isTraceEnabled()) {
          log.trace("已经设置了总页数, 不需要再查询总数.");
        }
      } else {
        Object parameterObj = boundSql.getParameterObject();
        MappedStatement mappedStatement =
            (MappedStatement) ReflectUtil.getFieldValue(delegate, "mappedStatement");
        queryTotalRecord(page, parameterObj, mappedStatement, connection);
      }

      String sql = boundSql.getSql();
      if (order != null) {
        sql = buildOrderSql(order, sql);
      }
      String pageSql = buildPageSql(page, sql);
      if (log.isDebugEnabled()) {
        log.debug("分页时, 生成分页pageSql: " + pageSql);
      }
      ReflectUtil.setFieldValue(boundSql, "sql", pageSql);

      return invocation.proceed();
    } else { // 查询结果的地方
      try {
        // 获取是否有分页Page对象
        Page<?> page = findPageObject(invocation.getArgs()[1]);
        // 获取是否有排序Order对象
        Order order = findOrderObject(invocation.getArgs()[1]);
        if (order != null) {
          orderThreadLocal.set(order);
        }
        if (page == null) {
          if (log.isTraceEnabled()) {
            log.trace("没有Page对象作为参数, 不是分页查询.");
          }
          return invocation.proceed();
        } else {
          if (log.isTraceEnabled()) {
            log.trace("检测到分页Page对象, 使用分页查询.");
          }
        }
        // 设置真正的parameterObj
        invocation.getArgs()[1] = extractRealParameterObject(invocation.getArgs()[1]);

        pageThreadLocal.set(page);
        Object resultObj = invocation.proceed(); // Executor.query(..)
        if (resultObj instanceof List) {
          /* @SuppressWarnings({ "unchecked", "rawtypes" }) */
          page.setDatas((List) resultObj);
        }
        return resultObj;
      } finally {
        pageThreadLocal.remove();
        orderThreadLocal.remove();
      }
    }
  }
  public Object intercept(Invocation invocation) throws Throwable {

    RoutingStatementHandler statementHandler = (RoutingStatementHandler) invocation.getTarget();
    BoundSql boundSql = statementHandler.getBoundSql();
    MetaObject metaStatementHandler = SystemMetaObject.forObject(statementHandler);

    BaseStatementHandler delegate =
        (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler, "delegate");
    MappedStatement mappedStatement =
        (MappedStatement) ReflectHelper.getValueByFieldName(delegate, "mappedStatement");
    Connection connection = (Connection) invocation.getArgs()[0];

    // 获取当前准备执行的行边界
    RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue("delegate.rowBounds");

    // 判断是否设置分页
    if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
      return invocation.proceed();
    }

    Configuration configuration =
        (Configuration) metaStatementHandler.getValue("delegate.configuration");
    Dialect.Type databaseType = null;
    // 获取当前的数据库方言
    try {

      databaseType =
          Dialect.Type.valueOf(configuration.getVariables().getProperty("dialect").toUpperCase());

    } catch (Exception e) {
      // ignore
      throw e;
    }

    if (databaseType == null) {
      throw new RuntimeException(
          "the value of the dialect property in configuration.xml is not defined : "
              + configuration.getVariables().getProperty("dialect"));
    }

    Dialect dialect = null;
    // 判断数据库方言
    switch (databaseType) {
      case ORACLE:
        dialect = new OracleDialect();
    }
    // 原始sql
    String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
    // 统计总数
    int count = getCount(connection, boundSql, configuration, mappedStatement);
    Object obj = boundSql.getParameterObject();
    if (null != obj && obj instanceof Map) {
      Map parameterObject = (Map) boundSql.getParameterObject();
      parameterObject.put("_dataCount", count);
    } else {
      throw new NullPointerException("service中getGridData的condition参数不能为空!");
    }
    // 设置拼接好的分页sql
    metaStatementHandler.setValue(
        "delegate.boundSql.sql",
        dialect.getPageSql(originalSql, rowBounds.getOffset(), rowBounds.getLimit()));

    // 重置行边界
    metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);

    metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);

    if (log.isDebugEnabled()) {
      log.debug("生成分页SQL : " + boundSql.getSql());
    }

    return invocation.proceed();
  }
예제 #14
0
  public Object intercept(Invocation ivk) throws Throwable {
    if (ivk.getTarget() instanceof RoutingStatementHandler) {
      RoutingStatementHandler statementHandler = (RoutingStatementHandler) ivk.getTarget();
      BaseStatementHandler delegate =
          (BaseStatementHandler) Reflections.getFieldValue(statementHandler, "delegate");
      MappedStatement mappedStatement =
          (MappedStatement) Reflections.getFieldValue(delegate, "mappedStatement");

      if (mappedStatement.getId().matches(pageSqlId)) { // 拦截需要分页的SQL
        BoundSql boundSql = delegate.getBoundSql();
        Object parameterObject =
            boundSql
                .getParameterObject(); // 分页SQL<select>中parameterType属性对应的实体参数,即Mapper接口中执行分页方法的参数,该参数不得为空
        if (parameterObject == null) {
          throw new NullPointerException("parameterObject尚未实例化!");
        } else {
          // 生成查询总数语句,并获取总数
          Connection connection = (Connection) ivk.getArgs()[0];
          String sql = boundSql.getSql();
          StringBuilder countSql = new StringBuilder();
          countSql.append("select count(1) from (").append(sql).append(") tmp_count");
          PreparedStatement countStmt = connection.prepareStatement(countSql.toString());
          // BoundSql countBS = new
          // BoundSql(mappedStatement.getConfiguration(),countSql.toString(),boundSql.getParameterMappings(),parameterObject);

          // 使用DefaultParameterHandler来对语句进行预处理
          DefaultParameterHandler defaultParameterHandler =
              new DefaultParameterHandler(mappedStatement, parameterObject, boundSql);
          defaultParameterHandler.setParameters(countStmt);
          ResultSet rs = countStmt.executeQuery();
          long count = 0;
          if (rs.next()) {
            count = rs.getLong(1);
          }
          rs.close();
          countStmt.close();
          // System.out.println(count);
          RequestBean requestBean = null;
          if (parameterObject instanceof RequestBean) { // 参数就是Page实体
            requestBean = (RequestBean) parameterObject;
            requestBean.setCount(count);
          } else if (parameterObject instanceof Map) {
            requestBean = (RequestBean) ((Map) parameterObject).get("requestBean");
            requestBean.setCount(count);
          } else { // 参数为某个实体,该实体拥有Page属性
            Field pageField = Reflections.getAccessibleField(parameterObject, "requestBean");
            if (pageField != null) {
              requestBean = (RequestBean) Reflections.getFieldValue(parameterObject, "requestBean");
              if (requestBean == null) requestBean = new RequestBean();

              requestBean.setCount(count);
              Reflections.setFieldValue(
                  parameterObject, "requestBean", requestBean); // 通过反射,对实体对象设置分页对象
            } else {
              throw new NoSuchFieldException(
                  parameterObject.getClass().getName() + "不存在 requestBean 属性!");
            }
          }
          String pageSql =
              dialectObj.getLimitString(sql, requestBean.getOffset(), requestBean.getPageSize());
          Reflections.setFieldValue(boundSql, "sql", pageSql); // 将分页sql语句反射回BoundSql.
          if (logger.isDebugEnabled()) {
            logger.debug("生成分页SQL : " + boundSql.getSql());
          }
        }
      }
    }

    return ivk.proceed();
  }