【问题标题】:Spring Data paginating and sorting on calculated fieldsSpring Data 对计算字段进行分页和排序
【发布时间】:2015-03-24 19:26:35
【问题描述】:

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

@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 data 生成自定义 order by 子句。一些映射之王告诉他根据所需的排序字段生成的代码

【问题讨论】:

    标签: sorting jpa pagination spring-data


    【解决方案1】:

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

    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()

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

    可选地,如果您想使用来自结果查询 (Page) 的结果 Pageable 对象,您可能必须删除之前添加的括号。 (用例:在数据表标题中显示排好序的列)

    【讨论】:

    • 对我来说,我还需要添加一个不安全的:JpaSort.unsafe(Sort.Direction.ASC, "(broadcastTitle)");
    猜你喜欢
    • 2014-07-12
    • 2016-11-19
    • 1970-01-01
    • 2017-06-03
    • 2018-09-22
    • 2016-07-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-04
    相关资源
    最近更新 更多