Spring Data Rest - 按多个属性排序
Posted
技术标签:
【中文标题】Spring Data Rest - 按多个属性排序【英文标题】:Spring Data Rest - Sort by multiple properties 【发布时间】:2016-01-06 05:07:36 【问题描述】:我有一个实体如下
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
有没有办法指定多个排序顺序?
谢谢!
【问题讨论】:
添加多个sort
属性。 sort=name,asc&sort=numberOfHands,desc
.
太棒了!那行得通..但这很奇怪..除了将字符串附加到URL之外,我不确定是否有直接的方法可以通过javascript生成此类URL..如果我错了,请告诉我..
为什么这就是网络(或 URL)的工作方式会很奇怪。您可以使用 javascript 生成您喜欢的任何 URL。见***.com/questions/24059773/…。
@M.Deinum - 你可能想把它变成一个答案,因为它是正确的。如果您无法通过 JavaScript 创建此类 URI,请归咎于 JavaScript 或您正在使用的库。 :)
【参考方案1】:
解决方案(tl;dr)
当想要对多个字段进行排序时,您只需在 URI 中多次输入 sort
参数即可。例如your/uri?sort=name,asc&sort=numberOfHands,desc
。然后 Spring Data 能够构造一个具有多种排序的Pageable
对象。
说明
对于如何为 URI 中的参数提交多个值并没有真正定义的标准。见Correct way to pass multiple values for same parameter name in GET request。
不过,Java Servlet Spec 中有一些信息提示 Java servlet 容器如何解析请求参数。
getParameterValues
方法返回一个String
对象数组,其中包含与参数名称关联的所有参数值。 ... - Java Servlet 规范,第 3.1 节
该部分中进一步说明的示例(尽管它混合了请求和正文数据)
例如,如果使用
a=hello
的查询字符串和a=goodbye&a=world
的帖子正文发出请求,则生成的参数集将按a=hello, goodbye, world
排序。
此示例显示,当一个参数(示例中为a
)多次出现时,结果将聚合到String[]
。
【讨论】:
bezkoder.com/spring-data-sort-multiple-columns【参考方案2】:这里是如何手动/以编程方式构造多排序对象。
Sort sort = Sort.by(
Sort.Order.asc("name"),
Sort.Order.desc("numberOfHands"));
return personRepository.findAll(sort);
注意:此解决方案不能直接解决所提出的原始问题,但可以帮助在搜索解决方案时遇到此问题的访问者如何从后端角度/以某种“硬编码”方式对多个属性进行排序。 (此解决方案不需要/采用任何 URI 参数)
【讨论】:
很有趣,虽然我猜这只会在服务器端起作用。 是的,当您需要在服务器端“硬编码”它时,这很有效。它使用 Spring 数据中的 Sort 类。我已经澄清了答案,所以现在希望更清楚:-) 假设我使用 JPQL 并跨多个表连接。我想根据两列对其进行排序。一个来自第一张桌子,另一个来自第二张桌子。如果我将它作为Sort.by(Sort.Direction.ASC,"first_table_col","second_table_col")
传递,我会得到一个异常,说在 First_table 中找不到“second_table_col”。有可能吗?
@PimHazebroek .. 这就是我最终所做的。清除表的别名并且它起作用了。谢谢。
在存储库中构造多排序的第二种方法:return this.bookRepository.findAll(Sort.by("published").descending().and(Sort.by("title")).a cending());
【参考方案3】:
当有动态字段时,您只需匹配字段并添加到排序列表中。
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)));
【讨论】:
以上是关于Spring Data Rest - 按多个属性排序的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Spring Data (JPA) 派生查询中按多个属性排序?
Spring Data Rest with Spring Security - 按当前用户查找所有内容
如何按角色限制对 Spring Data REST 投影的访问?