在Spring Data(JPA)派生查询中如何按多个属性排序?

96

我正在查看此页面上提供的示例(https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#jpa.repositories)关于方法命名的示例,是否可以创建像此类的复杂链式方法名称?

findByProgrammeAndDirectorAndProgDateBetweenOrderByProgDateStartTimeAsc
在他们给出的例子中,他们只对一个值进行OrderBy。在上面的例子中,ProgDateStartTime将是两个不同的值。

在他们提供的示例中,他们只对一个值进行OrderBy。在上面的示例中, ProgDate StartTime 将是两个单独的值。


1
你试过了吗?它应该可以工作。 - M. Deinum
4个回答

211

诀窍在于使用方向关键字AscDesc来简单地分隔您想要按其排序的属性。因此,您在查询方法中可能需要的是类似以下内容:

…OrderByProgDateAscStartTimeAsc

请注意,我们通过使用 Asc 来推断第一个属性定义,然后继续处理下一个属性。

一般来说,建议在方法名称超过一定长度或复杂度时,切换到基于 @Query 的查询。主要原因是对客户端调用这些非常长的方法很不方便。使用 @Query 您可以获得查询语言的全部功能以及较为简短的方法名,这有助于表达查询的意图。


有没有办法按照 JoinColumn 的 id 进行排序? - Laxman
@Laxman,请查看此链接:https://dev59.com/mofca4cB1Zd3GeqPeyNJ - dchang
如果没有任何条件,它就无法工作。因此,findByIdOrderByStartAscIdDesc 可以工作,但是 findAllOrderByStartAscIdDesc 不行。 - Selindek
Pageable对象中,是否可以将OrderBy方法关键字与Sort参数结合起来使用? - Conscript

12

我分享另一种代码片段,用于实现按多列排序的获取操作。

        List<Order> orders = new ArrayList<Order>();

        Order StartTimeOrder = new Order(Sort.Direction.DESC, "StartTime");
        orders.add(StartTimeOrder);
        Order progDateOrder = new Order(Sort.Direction.ASC, "ProgDate");
        orders.add(progDateOrder);
        return repository.findAll(Sort.by(orders));

2
谢谢,这正是我在寻找的。 - reiley
订单需要导入什么? - Michal.S
1
org.springframework.data.domain.Sort; org.springframework.data.domain.Sort.Order; org.springframework.data.domain.Sort; org.springframework.data.domain.Sort.Order; - abhinav kumar
@abhinavkumar 我可以用这个来设置一个日期范围吗?例如:Order StartTimeOrder = new Order(Sort.Direction.DESC, "StartTime"-"endTime"); - undefined

8
是的,这应该是可能的:
尝试这个:
findByProgrammeAndDirectorAndProgDateBetweenOrderByProgDateStartTimeAsc(String programme, String director, Date progStart, Date progEnd);

我还没有测试这段代码,但根据我之前做过的事情,它应该可以工作。


那个签名正确吗?我认为Between覆盖了progStart和progEnd,但是OrderByProgDateStartTimeAsc,是否需要额外的两个参数? - PDStat
1
@PaulStatham 我相信这是正确的。Between 需要两个日期,而 Order 不需要任何参数,因为您正在指示按列匹配的值进行排序,就像在 SQL 中一样... ORDER BY ProgDateStartTime ASC - Paulo Fidalgo

2
更加简洁一点:
return repository.findAll(
  Sort.by(List.of(
    new Order(Sort.Direction.DESC, "StartTime"),
    new Order(Sort.Direction.ASC, "ProgDate")
  ))
);

或者

return repository.findAll(
  Sort
  .by(Direction.DESC, "StartTime")
    .and(Sort.by(Sort.Direction.ASC, "ProgDate"))
);

我们可以将这个用于日期范围的查询,像这样返回 repository.findAll( Sort .by(Direction.DESC, "StartTime"-"EndTime") - undefined

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接