我们使用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子句。一些映射王告诉他生成的代码取决于所需的排序字段
答案 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对象,则可能必须删除先前添加的括号。 (用例:在数据表头中显示已排序的列)