Gui*_*lle 6 sorting pagination jpa 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);
Run Code Online (Sandbox Code Playgroud)
除排序支持外,其他一切工作都很好。
为了对计算所得的字段进行排序,Spring Data(或JPA吗?)会自动附加以下语句:
... order by c.toAllocateAmount desc
Run Code Online (Sandbox Code Playgroud)
这是无效的,因为在CreditAdvice实体上不存在c.toAllocateAmount。
但是在JPA控制台中测试的相同请求可以正常工作(由于select语句中的别名):
... order by toAllocateAmount desc
Run Code Online (Sandbox Code Playgroud)
问题是:有没有办法或一种解决方法来告诉Spring数据生成自定义order by子句。一些映射之王告诉他根据所需的排序字段生成的代码
简短答案:用括号封装原始可分页对象的排序字段,如下所示:
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)) ;
}
Run Code Online (Sandbox Code Playgroud)
要了解原因,请看一下使用分页请求时Spring Data如何生成“ order by”子句:QueryUtils.getOrderClause()
这听起来更像是骇客,而不是真正的解决方案...但是效果很好。
可选地,如果要使用结果查询(Page <T>)中的结果Pageable对象,则可能必须删除以前添加的括号。(用例:在数据表标题中显示排序的列)