分页和排序

本节介绍 Spring Data REST 如何使用 Spring Data Repository 分页和排序抽象。要熟悉这些功能,请参阅您使用的存储库实现的 Spring Data 文档(例如 Spring Data JPA)。

分页

Spring Data REST 不会返回大型结果集中的所有内容,而是识别一些 URL 参数来影响页面大小和起始页码。

如果您扩展了PagingAndSortingRepository<T, ID>并访问所有实体的列表,您将获得指向前 20 个实体的链接。要将页面大小设置为任何其他数字,请添加一个size参数,如下所示

https://127.0.0.1:8080/people/?size=5

上面的示例将页面大小设置为 5。

要在您自己的查询方法中使用分页,您需要更改方法签名以接受一个额外的Pageable参数,并返回一个PageSlice,而不是List。例如,以下查询方法导出到/people/search/nameStartsWith并支持分页

@RestResource(path = "nameStartsWith", rel = "nameStartsWith")
public Page findByNameStartsWith(@Param("name") String name, Pageable p);

Spring Data REST 导出器识别返回的Page/Slice,并在响应主体中为您提供结果,就像它对非分页响应一样,但会向资源添加额外的链接以表示数据的前一页和下一页。

每个分页响应使用 IANA 定义的链接关系 prevnext 返回指向结果的前一页和下一页的链接,这些链接基于当前页。但是,如果您当前处于结果的第一页,则不会呈现prev链接。对于结果的最后一页,不会呈现next链接。

考虑以下示例,我们在此将页面大小设置为 5

curl localhost:8080/people?size=5
{
  "_links" : {
    "self" : {
      "href" : "https://127.0.0.1:8080/persons{&sort,page,size}", (1)
      "templated" : true
    },
    "next" : {
      "href" : "https://127.0.0.1:8080/persons?page=1&size=5{&sort}", (2)
      "templated" : true
    }
  },
  "_embedded" : {
  	… data …
  },
  "page" : { (3)
    "size" : 5,
    "totalElements" : 50,
    "totalPages" : 10,
    "number" : 0
  }
}

在顶部,我们看到_links

1 self链接提供整个集合,并提供一些选项。
2 next链接指向下一页,假设页面大小相同。
3 在底部是有关页面设置的额外数据,包括页面大小、总元素、总页数以及您当前正在查看的页码。
在命令行上使用curl等工具时,如果您的语句中包含一个与号 (&),则需要将整个 URI 括在引号中。

请注意,selfnext URI 实际上是 URI 模板。它们不仅接受size,还接受pagesort作为可选标志。

如前所述,HAL 文档的底部包含有关页面的详细信息集合。这些额外的信息使您可以轻松地配置 UI 工具(如滑块或指示器)以反映用户查看数据时的整体位置。例如,前面示例中的文档显示我们正在查看第一页(页码从 0 开始)。

以下示例展示了点击next链接后会发生什么。

$ curl "https://127.0.0.1:8080/persons?page=1&size=5"
{
  "_links" : {
    "self" : {
      "href" : "https://127.0.0.1:8080/persons{&sort,projection,page,size}",
      "templated" : true
    },
    "next" : {
      "href" : "https://127.0.0.1:8080/persons?page=2&size=5{&sort,projection}", (1)
      "templated" : true
    },
    "prev" : {
      "href" : "https://127.0.0.1:8080/persons?page=0&size=5{&sort,projection}", (2)
      "templated" : true
    }
  },
  "_embedded" : {
	... data ...
  },
  "page" : {
    "size" : 5,
    "totalElements" : 50,
    "totalPages" : 10,
    "number" : 1 (3)
  }
}

这看起来非常相似,除了以下区别。

1 next链接现在指向另一个页面,表明它相对于self链接的相对位置。
2 现在出现了一个prev链接,为我们提供了前往上一页的路径。
3 当前页码现在是1(表示第二页)。

此功能允许您将屏幕上的可选按钮映射到这些超媒体控件,使您能够实现 UI 体验的导航功能,而无需硬编码 URI。实际上,用户可以从页面大小列表中进行选择,动态更改提供的内容,而无需重写顶部或底部的nextprev控件。

排序

Spring Data REST 识别使用存储库排序支持的排序参数。

要根据特定属性对结果进行排序,请添加一个sort URL 参数,其中包含要对结果进行排序的属性的名称。您可以通过在属性名称后附加逗号(,)以及ascdesc来控制排序方向。以下示例将使用PersonRepository上定义的findByNameStartsWith查询方法,用于所有名称以字母“K”开头的Person实体,并添加排序数据,以按name属性的降序对结果进行排序。

curl -v "https://127.0.0.1:8080/people/search/nameStartsWith?name=K&sort=name,desc"

要按多个属性对结果进行排序,请根据需要继续添加sort=PROPERTY参数。它们将按照它们在查询字符串中出现的顺序添加到Pageable中。结果可以按顶层属性和嵌套属性进行排序。使用属性路径表示法来表示嵌套的排序属性。不支持按可链接关联(即指向顶层资源的链接)进行排序。