Spring Data Rest - 按多个属性排序

102

我有一个以下的实体

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

有了Spring Data Rest(Gosling Release Train),我可以指定

localhost/Person?sort=name,asc

按名称升序排序。现在,如果我需要按numberOfHands降序和名称升序排序。我可以指定

localhost/Person?sort=numberOfHands,name,asc

但是,我无法具体说明。

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

有没有一种方法可以指定多个排序顺序?

谢谢!


12
添加多个sort属性。sort=name,asc&sort=numberOfHands,desc - M. Deinum
太好了!它有效了。但是这很奇怪。除了将字符串附加到URL之外,我不确定是否有一种直接通过JavaScript生成此类URL的方法。如果我错了,请告诉我。 - rakpan
1
为什么这会很奇怪呢?这只是网络(或URL)的工作方式。您可以使用JavaScript生成任何URL。请参见https://dev59.com/RWAg5IYBdhLWcg3wBXAR。 - M. Deinum
2
@M.Deinum - 如果你觉得这个回答是正确的,你可能想把它变成一个答案。如果你在使用JavaScript或使用的库创建此类URI时遇到问题,请责怪JavaScript或该库 :) - Oliver Drotbohm
3个回答

145

解决方案 (简短版)

想要按多个字段排序时,只需在URI中多次使用 sort 参数。例如:your/uri?sort=name,asc&sort=numberOfHands,desc。Spring Data 能够构建一个带有多个排序的 Pageable 对象。

说明

在 URI 中提交多个参数值没有真正定义标准。请参见 正确的方法传递 GET 请求中相同参数名称的多个值

然而,在 Java Servlet 规范 中有一些信息提示 Java Servlet 容器如何解析请求参数。

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

该节中的示例还指出(虽然混合了请求和 body 数据)

例如,如果使用查询字符串 a=hello 和 post body a=goodbye&a=world 进行请求,则生成的参数集将按 a=hello, goodbye, world 排序。

该示例显示,当参数(例如示例中的 a)出现多次时,结果将聚合为一个 String[]


https://bezkoder.com/spring-data-sort-multiple-columns - sasynkamil

65

以下是手动或通过程序构建多重排序对象的方法。

Sort sort = Sort.by(
    Sort.Order.asc("name"),
    Sort.Order.desc("numberOfHands"));
return personRepository.findAll(sort);
注意:此解决方案并没有直接解决原始问题,但可以帮助那些在搜索如何从后端的角度/以某种“硬编码”的方式按多个属性排序的解决方案时着陆在这个问题上的访问者。 (此解决方案不需要/不采用任何URI参数)

1
有趣,不过我猜这只能在服务器端运行。 - aboger
是的,在服务器端需要“硬编码”时,这是有效的。它使用Spring数据中的Sort类。我已经澄清了答案,希望现在更清楚了 :-) - BitfulByte
假设我使用JPQL并跨越多个表进行连接。我想根据两列对其进行排序。一列来自第一个表,另一列来自第二个表。如果我将其传递为Sort.by(Sort.Direction.ASC,"first_table_col","second_table_col"),我会收到一个异常,说“First_table”中找不到“second_table_col”。这是可能的吗? - padmanabhanm
@iamL 或许尝试使用第二个表的前缀? - BitfulByte
1
@PimHazebroek .. 这就是我最终所做的。清除了表的别名,它就可以工作了。谢谢。 - padmanabhanm
1
在存储库中构建多重排序的第二种方法:return this.bookRepository.findAll(Sort.by("published").descending().and(Sort.by("title")).ascending()); - Seldo97

0

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

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

如果您正在使用分页功能,则可以直接在PageRequest请求中添加。
return personRepository.findPersons(PageRequest.of(pageNo, pageSize, Sort.by(sorts)));

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