public Object intercept(Invocation invocation) throws Throwable {

    StatementHandler handler = (StatementHandler) invocation.getTarget();
    MetaObject metaObject = MetaObject.forObject(handler);

    Page page = pageByMetaObject(metaObject);
    if (page == null || (page.getPageCount() == 0 && page.getPageSize() == 0))
      return invocation.proceed();

    Configuration configuration = (Configuration) metaObject.getValue("delegate.configuration");
    BoundSql orgBoundSql = (BoundSql) metaObject.getValue("delegate.boundSql");
    if (page.getCount() == 0) {
      MappedStatement mappedStatement =
          (MappedStatement) metaObject.getValue("delegate.mappedStatement");
      page.setCount(
          totalCount(
              (Connection) invocation.getArgs()[0], orgBoundSql, configuration, mappedStatement));
    }

    metaObject.setValue(
        "delegate.boundSql.sql",
        searchDialectByDbTypeEnum(configuration, page)
            .spellPageSql(orgBoundSql.getSql(), page.getOffset(), page.getLimit()));
    logger.debug("pagination sql : {}", handler.getBoundSql().getSql());

    return invocation.proceed();
  }
  public Object intercept(Invocation invocation) throws Throwable {

    StatementHandler statementHandler = (StatementHandler) invocation.getTarget();

    BoundSql boundSql = statementHandler.getBoundSql();

    String sql = tryConvertSql(boundSql);

    if (StringUtils.isNotEmpty(sql)) {
      Reflections.setFieldValue(boundSql, "sql", sql);
    }

    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);
   }
 }
  @Override
  public Object intercept(Invocation invocation) throws Throwable {
    StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
    ParameterHandler parameterHandler = statementHandler.getParameterHandler();
    BoundSql boundSql = statementHandler.getBoundSql();

    MetaObject metaStatementHandler =
        MetaObject.forObject(
            statementHandler, DEFAULT_OBJECT_FACTORY, DEFAULT_OBJECT_WRAPPER_FACTORY);
    RowBounds rowBounds = (RowBounds) metaStatementHandler.getValue("delegate.rowBounds");
    // 没有分页参数
    if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
      return invocation.proceed();
    }

    Configuration configuration =
        (Configuration) metaStatementHandler.getValue("delegate.configuration");
    Dialect dialect = DialectFactory.buildDialect(configuration);
    String originalSql = (String) metaStatementHandler.getValue("delegate.boundSql.sql");
    // 获取总记录数
    Page<?> page = (Page<?>) rowBounds;
    String countSql = dialect.getCountString(originalSql);
    Connection connection = (Connection) invocation.getArgs()[0];
    int total = getTotal(parameterHandler, connection, countSql);
    page.setTotalCount(total);

    // 设置物理分页语句
    metaStatementHandler.setValue(
        "delegate.boundSql.sql",
        dialect.getLimitString(originalSql, page.getOffset(), page.getLimit()));
    // 屏蔽mybatis原有分页
    metaStatementHandler.setValue("delegate.rowBounds.offset", RowBounds.NO_ROW_OFFSET);
    metaStatementHandler.setValue("delegate.rowBounds.limit", RowBounds.NO_ROW_LIMIT);
    if (logger.isDebugEnabled()) {
      logger.debug("分页SQL : " + boundSql.getSql());
    }
    return invocation.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();
      }
    }
  }