/** 在HQL的后面添加分页参数定义的orderBy, 辅助函数. */
  protected String setPageRequestToHql(String hql, PageRequest pageRequest) {

    if (CollectionUtils.isEmpty(pageRequest.getSort())) {
      return hql;
    }

    StringBuilder builder = new StringBuilder(hql);
    builder.append(" order by");

    for (PageRequest.Sort orderBy : pageRequest.getSort()) {
      builder.append(String.format(" %s %s,", orderBy.getProperty(), orderBy.getDir()));
    }

    builder.deleteCharAt(builder.length() - 1);

    return builder.toString();
  }
  /**
   * 设置分页参数到Criteria对象,辅助函数.
   *
   * @param c Hibernate Criteria
   * @param pageRequest 分页请求参数
   * @return {@link org.hibernate.Criteria}
   */
  protected Criteria setPageRequestToCriteria(Criteria c, PageRequest pageRequest) {
    Assert.isTrue(pageRequest.getPageSize() > 0, "分页大小必须大于0");

    c.setFirstResult(pageRequest.getOffset());
    c.setMaxResults(pageRequest.getPageSize());

    if (pageRequest.isOrderBySetted()) {
      for (PageRequest.Sort sort : pageRequest.getSort()) {
        Order order = null;
        if (sort.getDir().equals(PageRequest.Sort.ASC)) {
          order = Order.asc(sort.getProperty());
        } else {
          order = Order.desc(sort.getProperty());
        }
        c.addOrder(order);
      }
    }

    return c;
  }
  /**
   * 根据分页请求参数与Query获取分页请求对象
   *
   * @param request 分页请求参数对象
   * @param query Hibernate Query
   * @return {@link Page}
   */
  public <X> Page<X> findPage(PageRequest request, Query query) {
    Page<X> page = new Page<X>(request);

    if (request == null) {
      return page;
    }

    AbstractQueryImpl impl = (AbstractQueryImpl) query;

    String queryString = setPageRequestToHql(impl.getQueryString(), request);
    ReflectionUtils.setFieldValue(impl, "queryString", queryString);

    if (request.isCountTotal()) {
      long totalCount = 0;

      if (impl.hasNamedParameters()) {
        Map<String, TypedValue> map = ReflectionUtils.getFieldValue(impl, "namedParameters");
        Map<String, Object> values = new HashMap<String, Object>();

        for (Map.Entry<String, TypedValue> entry : map.entrySet()) {
          values.put(entry.getKey(), entry.getValue().getValue());
        }

        totalCount = countHqlResult(impl.getQueryString(), values);

      } else {
        List<Object> values = ReflectionUtils.invokeGetter(impl, "values");
        totalCount = countHqlResult(impl.getQueryString(), values.toArray());
      }

      page.setTotalItems(totalCount);
    }

    impl.setFirstResult(request.getOffset());
    impl.setMaxResults(request.getPageSize());

    List result = impl.list();
    page.setResult(result);

    return page;
  }
  /**
   * 根据分页参数与Criteria获取分页对象
   *
   * @param request 分页请求参数
   * @param c Criteria对象
   * @return {@link Page}
   */
  public Page<T> findPage(PageRequest request, Criteria c) {

    Page<T> page = new Page<T>(request);

    if (request == null) {
      return page;
    }

    if (request.isCountTotal()) {
      long totalCount = countCriteriaResult(c);
      page.setTotalItems(totalCount);
    }

    setPageRequestToCriteria(c, request);

    List result = c.list();
    page.setResult(result);

    return page;
  }