将Spring Data JPA与QueryDsl一起使用,分页查询会破坏排序

时间:2014-12-10 02:28:52

标签: spring jpa spring-data spring-data-jpa querydsl

鉴于以下查询,我的结果按订单号降序排序。在尝试返回分页结果时,排序似乎打破了。我没有使用.orderBy()表达式并将QSort实例添加到我的QPageRequest中。我已经尝试直接调用applySorting()方法并传递QSort,但是出于所有密集目的,分页调用会破坏我尝试的任何类型的排序。

我正在使用QueryDsl 3.3.4和Spring Data JPA 1.6.4。由Spring IO BOM 1.0.3导入。

public List<Object[]> findAll(PersonProfile personProfile) {
    QOrderStop shipper = new QOrderStop("shipper");
    QOrderStop consignee = new QOrderStop("consignee");
    JPQLQuery query = this.from(order)
            .leftJoin(order.orderStops, shipper).on(shipper.originalStopSequence.eq(BigDecimal.valueOf(1)))
            .leftJoin(order.orderStops, consignee).on(consignee.originalStopSequence.intValue().eq(order.orderStops.size()))
            .where(order.company.eq(company).and(OrderExpressions.customerCodePredicate(order, personProfile)))
            .orderBy(order.number.desc());

    //this.getQuerydsl().applyPagination(new QPageRequest(0, 10), query);

    return query
            .list(
                    order.number, order.status, order.shipperReferenceNumber, order.consigneeReferenceNumber,
                    order.shipperCustomer.billingCity, order.shipperCustomer.state,
                    shipper.latestScheduleDate, shipper.latestScheduleTime,
                    order.consigneeCustomer.billingCity, order.consigneeCustomer.state,
                    consignee.latestScheduleDate, consignee.latestScheduleTime
            ).stream()
            .map(Tuple::toArray)
            .collect(toList());
}

编辑 - 使用.limit(20)进行分页而不是.applyPagination()

在query.limit(20)之前的

query.toString()

select order1
from Order order1
  left join order1.orderStops as shipper on shipper.originalStopSequence = ?1
  left join order1.orderStops as consignee on cast(consignee.originalStopSequence integer) = size(order1.orderStops)
where order1.company = ?2 and (order1.customer = ?3 or order1.billTo in ?4 or order1.shipper in ?5 or order1.consignee in ?5)
order by order1.number desc
在query.limit(20)之后

query.toString() - 无变化

select order1
from Order order1
  left join order1.orderStops as shipper on shipper.originalStopSequence = ?1
  left join order1.orderStops as consignee on cast(consignee.originalStopSequence integer) = size(order1.orderStops)
where order1.company = ?2 and (order1.customer = ?3 or order1.billTo in ?4 or order1.shipper in ?5 or order1.consignee in ?5)
order by order1.number desc

EclipseLink的最终查询输出

SELECT * FROM (SELECT * FROM (SELECT EL_TEMP.*, ROWNUMBER() OVER() AS EL_ROWNM FROM (SELECT t0.OHOR# AS a1, t0.OHORST AS a2, t0.OHSRF# AS a3, t0.OHCRF# AS a4, t1.CUBCTY AS a5, t1.CUBST AS a6, t2.BSLSDT AS a7, t2.BSLSTM AS a8, t3.CUBCTY AS a9, t3.CUBST AS a10, t4.BSLSDT AS a11, t4.BSLSTM AS a12 FROM LIB.DPORDHP t0 LEFT OUTER JOIN LIB.DPORDSP t2 ON (((t2.BSOR# = t0.OHOR#) AND ((t2.BSOL# = t0.OHORS#) AND (t2.BSCM = t0.OHCM))) AND (t2.BSRSQS = ?)) LEFT OUTER JOIN LIB.DPORDSP t4 ON (((t4.BSOR# = t0.OHOR#) AND ((t4.BSOL# = t0.OHORS#) AND (t4.BSCM = t0.OHCM))) AND (CAST(t4.BSRSQS AS integer) = (SELECT COUNT(t5.BSOR#) FROM LIB.DPORDSP t5 WHERE ((t5.BSOR# = t0.OHOR#) AND ((t5.BSOL# = t0.OHORS#) AND (t5.BSCM = t0.OHCM)))))), LIB.SWCUSTP t3, LIB.SWCUSTP t1 WHERE (((t0.OHCM = ?) AND ((((t0.OHCUST = ?) OR (t0.OHBID IN (?,?))) OR (t0.OHSID IN (?,?,?,?,?,?,?,?,?,?))) OR (t0.OHCID IN (?,?,?,?,?,?,?,?,?,?)))) AND (((t1.CUCID = t0.OHSID) AND (t1.CUCM = t0.OHCM)) AND ((t3.CUCID = t0.OHCID) AND (t3.CUCM = t0.OHCM)))) ORDER BY t0.OHOR# DESC) AS EL_TEMP) AS EL_TEMP2 WHERE EL_ROWNM <= ?) AS EL_TEMP3 WHERE EL_ROWNM > ?

1 个答案:

答案 0 :(得分:0)

我不知道applyPagination如何打破排序,但是在这里使用query.limit和query.offset可能更直观,因为你在存储库方法中。

...
.orderBy(order.number.desc()).
.limit(pageSize)
.offset((page-1) * pageSize);