多个排序可选查询 - 带有分页的Spring REST控制器配置

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了多个排序可选查询 - 带有分页的Spring REST控制器配置相关的知识,希望对你有一定的参考价值。

我想构建一个可以处理多个可选排序查询的spring控制器。根据spring.io规范,这些查询应该格式化

&sort=name,desc&sort=code,desc

正如EduardoFernandes所讨论的那样

我知道这可以通过一个sort实例来完成,其中值将被排序,并且方向根据Gregg单独给出但是与Spring规范不匹配或处理多个排序值。

我不确定如何将spring spec格式的多个查询转换为一个Sort,我可以将其传递给我的PageRequest,然后传递到我的存储库。此外,我希望能够使这些可选,如果可能的话,如果我可以使用基于@Anotation的配置,如果根据Rasheed Amir(@SortDefault)实现这一点需要默认值,那将会很棒

以下是我正在使用的基础知识..

@Entity
@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class Subject {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    private String name;
    private String code; 
...

知识库

public interface SubjectRepository extends JpaRepository<Subject, Long> {
}

服务

@Override
public Page<SubjectDTO> listSubjectsPageble(PageRequest pageableRequest) {
    return subjectRepository.findAll(pageableRequest)
            .map(subjectMapper::subjectToSubjectDTO);
}

调节器

@GetMapping
@ResponseStatus(HttpStatus.OK)
@PreAuthorize("hasRole('LECTURER')")
public Page<SubjectDTO> getSubjects(
        @RequestParam("page") int page,
        @RequestParam("size") int size,
        @RequestParam("sort") String sort

) {

    return subjectService.listSubjectsPageble(PageRequest.of(page, size, new Sort(sort)));
}

所以这里在控制器中我不知道如何处理从填充RequestParam的排序,根据Ralph我应该能够使用类似下面的东西从一个参数获取多个值,但我不知道如何将其传递给排序。

我知道一个Sort可以采用多个参数但只有一个排序方向。然后粗略我想让它们成为可选的。

@RequestParam MultiValueMap<String, String> params

请帮忙,我还是一个菜鸟:)谢谢

编辑

由于Dullimeister的帖子,我解决了我的一些问题但是这种方法感觉有点乱,但仍然没有处理多个排序参数。有没有人知道更好的方法或这是要走的路?

@GetMapping
    @ResponseStatus(HttpStatus.OK)
    @PreAuthorize("hasRole('LECTURER')")
    public Page<SubjectDTO> getSubjects(
            @RequestParam(value = "page", defaultValue = "0", required = false) int page,
            @RequestParam(value = "size", defaultValue = "10", required = false) int size,
            @RequestParam(value = "sort", defaultValue = "name,ASC", required = false) String sortBy

    ) {
        String[] sort = sortBy.split(",");
        String evalSort = sort[0];
        String sortDirection = sort[1];
        Sort.Direction evalDirection = replaceOrderStringThroughDirection(sortDirection);
        Sort sortOrderIgnoreCase = Sort.by(new Sort.Order(evalDirection,evalSort).ignoreCase());

        return subjectService.listSubjectsPageble(PageRequest.of(page, size, sortOrderIgnoreCase));
    }

    private Sort.Direction replaceOrderStringThroughDirection(String sortDirection) {
        if (sortDirection.equalsIgnoreCase("DESC")){
            return Sort.Direction.DESC;
        } else {
            return Sort.Direction.ASC;
        }
    }

最终解决方案感谢大家,这就是我最终的结果。不知道它是否是完美的方式,但它的工作原理:)我不得不用一个分号替换逗号,因为FormattingConversionService自动将单个排序参数解析为字符串而不是Sting []

@GetMapping
@ResponseStatus(HttpStatus.OK)
@PreAuthorize("hasRole('LECTURER')")
public Page<SubjectDTO> getSubjects(
        @RequestParam(value = "page", defaultValue = "0", required = false) int page,
        @RequestParam(value = "size", defaultValue = "10", required = false) int size,
        @RequestParam(value = "sort", defaultValue = "name;ASC", required = false) String[] sortBy

Sort allSorts = Sort.by(
        Arrays.stream(sortBy)
                .map(sort -> sort.split(";", 2))
                .map(array ->
                        new Sort.Order(replaceOrderStringThroughDirection(array[1]),array[0]).ignoreCase()
                ).collect(Collectors.toList())
);
return subjectService.listSubjectsPageble(PageRequest.of(page, size, allSorts));

private Sort.Direction replaceOrderStringThroughDirection(String sortDirection) {
    if (sortDirection.equalsIgnoreCase("DESC")){
        return Sort.Direction.DESC;
    } else {
        return Sort.Direction.ASC;
    }
答案

为什么不在控制器中使用Pageable?

Pageable可以处理许多排序查询,每个查询都将存储在订单列表中。此外,不需要任何可分页参数。如果未在url中传递它们,则pageable将包含默认值(page = 0,size = 20)。您可以使用@PageableDefault批注更改默认值。

GET ... / test?sort = name,desc&sort = code,desc enter image description here

以上是关于多个排序可选查询 - 带有分页的Spring REST控制器配置的主要内容,如果未能解决你的问题,请参考以下文章

带有分页的 Spring Data JPA 方法查询给了我一个错误

带有分页的 Spring Data 和 Native Query

带有分页的MySql查询中的随机值

使用带有mysql的spring MVC实现分页的最佳方法是啥

带有分页的 Spring-Data FETCH JOIN 不起作用

如何在 Spring Data JPA 中使用带有分页的投影接口?