Spring Data分页和计算字段的排序

时间:2015-01-26 11:25:05

标签: sorting jpa pagination spring-data

我们使用spring数据在分页和可排序表中显示计算字段列表:

@Query(value = 
    "select new com.mycompany.SomeDTO( " +
    "    c.id as creditAdviceId, " +
    "    case when c.associationAmount.assignedAmountNet = 0 "+
    "        then c.netReceivedAmount  "+
    "        else 0 "+
    "        end "+
    "        as toAllocateAmount, " +
    "    c.netReceivedAmount - c.associationAmount.assignedAmountNet "+
    "        as notAllocatedAmount",
    ") " +
    "from CreditAdvice c where c.debtorCompany.id = :companyId",

    countQuery = "select count(c.id) from CreditAdvice c where c.debtorCompany.id = :companyId")

Page<SomeDTO> creditAdviceMonitoring(@Param("companyId") long companyId, Pageable pageable);

除了排序支持外,其他所有工作都很好。

要对计算字段进行排序,Spring Data(或JPA?)会自动附加此语句:

... order by c.toAllocateAmount desc

这是无效的,因为CreditAdvice实体上不存在c.toAllocateAmount。

但是在JPA控制台中测试的相同请求工作正常(因为select语句中的别名):

... order by toAllocateAmount desc

问题是:是否有方法或解决方法,告诉spring数据生成自定义order by子句。一些映射王告诉他生成的代码取决于所需的排序字段

1 个答案:

答案 0 :(得分:5)

简短回答:使用括号从原始可分页对象封装已排序字段,如下所示:

public static Pageable parenthesisEncapsulation(Pageable pageable) {

    List<Sort.Order> orders = new ArrayList<>() ;
    for (Sort.Order order : pageable.getSort()) {
        String encapsulatedProperty = "("+order.getProperty()+")" ;
        orders.add( new Sort.Order(order.getDirection(), encapsulatedProperty));
    }

    return new PageRequest(pageable.getPageNumber(), pageable.getPageSize(), new Sort(orders)) ;
}

要了解原因,请查看Spring Data在使用分页请求时如何生成“order by”子句:QueryUtils.getOrderClause()

这听起来更像是一个黑客而不是真正的解决方案......但它运作正常。

Optionnaly,如果要从结果查询(Page&lt; T&gt;)中使用生成的Pageable对象,则可能必须删除先前添加的括号。 (用例:在数据表头中显示已排序的列)