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);
   }
 }
  @SuppressWarnings({"rawtypes", "unchecked"})
  @Override
  public Object intercept(Invocation invocation) throws Throwable {
    final String name = invocation.getMethod().getName();
    final Object target = invocation.getTarget();
    if (target instanceof StatementHandler) {
      pagination(invocation, (StatementHandler) target);
    } else if (target instanceof Executor) {
      autoMap(invocation, name);
    } else if (target instanceof ResultSetHandler) {
      Object result = invocation.proceed();
      if (result instanceof List) {
        Page page = PAGE_THREAD_LOCAL.get();
        if (page != null) {
          page.addAll((List) result);
          PAGE_THREAD_LOCAL.remove();
          return page;
        }
      }
      return result;
    }

    return invocation.proceed();
  }
  @SuppressWarnings({"rawtypes", "unchecked"})
  private void autoMap(Invocation invocation, String name) throws ClassNotFoundException {
    final Object[] queryArgs = invocation.getArgs();
    final MappedStatement ms = (MappedStatement) queryArgs[0];
    final Object parameter = queryArgs[1];
    String statementId = ms.getId();
    MapperMeta meta = getMapperMeta(ms.getConfiguration(), statementId);
    if (meta.isFillEntity()) {
      // 将泛型类加入到参数中供CrudTemplate使用
      if (parameter != null) {
        Map map;
        if (parameter instanceof Map) {
          map = (HashMap) parameter;
          map.put(CrudProvider.CLASS_KEY, meta.getEntity());
        } else {
          map = new HashMap();
          map.put(CrudProvider.PARA_KEY, parameter);
          map.put(CrudProvider.CLASS_KEY, meta.getEntity());
        }
        queryArgs[1] = map;
      } else {
        queryArgs[1] = meta.getEntity();
      }
    }

    if (meta.isFillResultMap()) {
      MetaObject metaMappedStatement = getMetaObject(ms);
      metaMappedStatement.setValue("resultMaps", meta.getResultMaps());
    }

    if (name.equals("query")) {
      final RowBounds rowBounds = (RowBounds) queryArgs[2];
      if (rowBounds == null || rowBounds == RowBounds.DEFAULT) {
        Page p = findPageParameter(queryArgs[1]);
        if (p != null) {
          queryArgs[2] = new RowBounds(p.getOffset(), p.getLimit());
        }
      }
    }
  }