繁体   English   中英

如何对 Spring 数据 JPA 中的特定页码进行排序?

[英]How to sort a particular page number in Spring Data JPA?

我有这个分页问题,当我尝试在特定页码上按字段 header对表进行排序时, PageRequest.of(page-1, 10, sort)正在对整个表而不是特定页面进行排序。 因此,该页面中返回的记录与排序前的前一条记录不同。

代码:

@Override
public Page<User> getPageAndSort(String field, String direction, int page) {

    Sort sort = direction.equalsIgnoreCase(Sort.Direction.ASC.name())
            ? Sort.by(field).ascending()
            : Sort.by(field).descending();

    Pageable pageable = PageRequest.of(page-1, 10, sort);

    return userRepo.findAll(pageable);
}

例如。 我只想在第 1 页按 id 排序。 从第 1 页返回已排序的记录。页面的 rest 或整个记录不应受到影响。

谢谢你。

编辑:

我有解决这个问题的方法。 从以下位置获取页面后:

Page<User> page = userService.findPage(currentPage);

我得到page.getContent()列表,然后传递给方法 sortList:

userService.sortList(new ArrayList<>(page.getContent()), field, sortDir)

排序实现:

public ArrayList<User> sortList(ArrayList<User> users, String field, String direction) {
    users.sort((User user1, User user2) -> {

        try {
            Field field1 = user1.getClass().getDeclaredField(field);
            field1.setAccessible(true);
            Object object1 = field1.get(user1);

            Field field2 = user2.getClass().getDeclaredField(field);
            field2.setAccessible(true);
            Object object2 = field2.get(user2);

            int result = 0;

            if (isInt(object1.toString())) {
                result = Integer.parseInt(object1.toString()) - Integer.parseInt(object2.toString());
            } else {
                result = object1.toString().compareToIgnoreCase(object2.toString());
            }

            if (result > 0) {
                return direction.equalsIgnoreCase("asc") ? 1 : -1;
            }

            if (result < 0) {
                return direction.equalsIgnoreCase("asc") ? -1 : 1;
            }

            return 0;

        } catch (Exception e) {
            Log.error(e.toString());
            return 0;
        }
    });

    return users;
}

有了这个解决方法。 我成功地按列 header 对特定页面进行了排序,而不影响页面的 rest。 但它不是标准的,因为它不使用PageRequest.of() from Spring Data JPA 我建议测试代码并彻底检查它。

我认为 if 条件可以解决问题。 根据条件创建 Pageable 实例。

@Override
public Page<User> getPageAndSort(String field, String direction, int page) {

    Sort sort = direction.equalsIgnoreCase(Sort.Direction.ASC.name())
            ? Sort.by(field).ascending()
            : Sort.by(field).descending();

    Pageable pageable = (page == 1)?PageRequest.of(page-1, 10, sort)
    :PageRequest.of(page-1, 10);

    return userRepo.findAll(pageable);
}

参考资料: https://www.baeldung.com/spring-data-jpa-pagination-sorting#:~:text=We%20can%20create%20a%20PageRequest%20object%20by%20passing,%280%2C%202% 29%3B%20Pageable%20secondPageWithFiveElements%20%3D%20PageRequest.of%20%281%2C%205%29%3B

我认为这有帮助。

我不认为有一种简单的方法可以在数据库中进行这种排序,并且由于您处理的是单个页面 memory 无论如何,因为您将其呈现给 UI,所以我只是将其排序为 memory。

或者,您可以 go 使用自定义 SQL 语句,结构如下:

SELECT * FROM (
    SELECT * FROM WHATEVER
    ORDER BY -- sort clause defining the pagination
    OFFSET ... LIMIT ... -- note that this clause is database dependent.
) ORDER BY -- your sort criteria within the page goes here

您必须以编程方式构建此 SQL 语句,因此您不能使用 Spring 数据的特殊功能,如带注释的查询或查询派生。

我不确定,我得到了你的问题,但如果你想要某个排序的页面,数据库肯定应该创建查询计划,对所有数据进行排序并返回排序数据的某个偏移量(页面)。 如果不对整个数据进行排序,就不可能得到一个排序的页面。

我相信您只想对给定页面上的数据进行排序,这很难通过数据库查询进行管理,数据库查询可能会对整个数据进行排序并为您提供第 n 页。

我建议在以相同顺序检索后在给定页面上进行反向操作。

  1. 从数据库中检索第 n 页,总是 asc。

  2. 如果需要,根据方向进行反向操作。

这应该比依赖数据库进行排序操作更快。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM