Spring Data Rest - 按多个属性排序

问题描述 投票:0回答:3

我有一个实体如下:

class Person{
    String id;
    String name;
    String numberOfHands;
}

使用 Spring Data Rest(Gosling Release Train),我可以指定

localhost/Person?sort=name,asc

用于

name
升序排序。现在,在我需要按
numberOfHands
降序和
name
升序排序的情况下。我可以指定

localhost/Person?sort=numberOfHands,name,asc

但是,我无法指定

localhost/Person?sort=numberOfHands,desc,name,asc

有没有办法指定多个排序顺序?

spring spring-data spring-data-jpa spring-data-rest
3个回答
148
投票

解决方案(长;博士)

当想要对多个字段进行排序时,您只需在 URI 中多次放置

sort
参数即可。例如
your/uri?sort=name,asc&sort=numberOfHands,desc
。然后 Spring Data 就能够构造具有多种排序的
Pageable
对象。

说明

关于如何为 URI 中的参数提交多个值,并没有真正定义的标准。请参阅在 GET 请求中为同一参数名称传递多个值的正确方法

然而,Java Servlet Spec 中有一些信息暗示了 Java servlet 容器如何解析请求参数。

getParameterValues
方法返回一个
String
对象数组,其中包含与参数名称关联的所有参数值。 ... - Java Servlet 规范,第 3.1 节

该部分中的示例进一步说明(尽管它混合了请求和正文数据)

例如,如果使用查询字符串

a=hello
和帖子正文
a=goodbye&a=world
发出请求,则生成的参数集将按
a=hello, goodbye, world
排序。

此示例显示,当多次出现某个参数(示例中的

a
)时,结果将聚合到
String[]
中。


66
投票

以下是如何手动/编程构造多排序对象。

Sort sort = Sort.by(
    Sort.Order.asc("name"),
    Sort.Order.desc("numberOfHands"));
return personRepository.findAll(sort);

注意:此解决方案并不直接解决最初提出的问题,但可能会帮助遇到此问题的访问者,同时寻找如何从后端角度/以某种“硬编码”的方式对多个属性进行排序的解决方案。 (此解决方案不需要/采用任何 URI 参数)


1
投票

当存在动态字段时,您只需与字段进行匹配并添加到排序列表中即可。

List<Sort.Order> sorts= new ArrayList<>();
if (sort == "name" && sortingOrder.equalsIgnoreCase("DESC")) {
   sorts.add(new Sort.Order(Sort.Direction.DESC,"name"));
} else if (sort == "numberOfHands" && sortingOrder.equalsIgnoreCase("DESC")) {
  sorts.add(new Sort.Order(Sort.Direction.DESC,"numberOfHands"));
}
     
return personRepository.findAll(Sort.by(sorts)); 

如果你使用Pagination则直接在PageRequest请求中添加。

return personRepository.findPersons(PageRequest.of(pageNo, pageSize, Sort.by(sorts)));
© www.soinside.com 2019 - 2024. All rights reserved.