Spring 数据剩余 - 按多个属性排序

Spring Data Rest - Sort by multiple properties

我有一个实体如下

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

使用 Spring 数据休息(Gosling 发布火车),我可以指定

localhost/Person?sort=name,asc

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

localhost/Person?sort=numberOfHands,name,asc

但是,我无法指定

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

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

谢谢!

解决方案 (tl;dr)

当想要对多个字段进行排序时,只需在 URI 中多次放置 sort 参数即可。例如 your/uri?sort=name,asc&sort=numberOfHands,desc。 Spring 数据然后能够构建具有多种类型的 Pageable 对象。

说明

关于如何为 URI 中的参数提交多个值,并没有真正定义的标准。参见 Correct way to pass multiple values for same parameter name in GET request

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

The getParameterValues method returns an array of String objects containing all the parameter values associated with a parameter name. ... - Java Servlet Spec, section 3.1

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

For example, if a request is made with a query string of a=hello and a post body of a=goodbye&a=world, the resulting parameter set would be ordered a=hello, goodbye, world.

此示例表明,当一个参数(示例中的 a)出现多次时,结果将聚合到 String[]

下面是如何构造多排序对象manually/programatically。

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

注意:此解决方案并未直接解决最初提出的问题,但可能会帮助那些在搜索解决方案时遇到此问题的访问者如何从后端角度/某种程度上对多个属性进行排序"hardcoded" 方法。 (此解决方案不 require/take 任何 URI 参数)

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

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中添加Request。

return personRepository.findPersons(PageRequest.of(pageNo, pageSize, Sort.by(sorts)));