如何编辑 Spring Pageable 对象?

How to edit a Spring Pageable object?

我需要能够编辑 Pageable 对象,更具体地说是 Sorts 之一。

我有一些 DTO Member,其中有一个 属性 emailAddress。客户端不知道,这是通过来自 2 个不同实体的查询收集的信息,AccountInviteMember 总是有其中之一。 这很好用,我在 repo 中执行标准 JPA 查询并在将其转换为 DTO 之前收集所需的信息。

现在我们要对这个引用的属性进行排序。没关系。我可以创建一个包含类似 ORDER BY coalesce(i.emailAddress, a.emailAddress) ASC 的查询,效果很好。如果客户端没有在 Pageable 对象中传递任何排序,我就使用这个排序,如果客户端确实通过了排序,那么我调用一个没有这个默认排序的不同版本的查询。

但是现在客户想要对此进行排序 emailAddress 属性 并且麻烦开始了。直接将 Pageable 传递给 Repository 是行不通的,因为没有 属性 emailAddress。所以我觉得不用担心!让我们检查我的代码是否对此 属性 进行排序,并根据参数执行我的查询的特殊版本。

if (pageable.getSort().isSorted()) {
    Sort.Order emailAddressOrder = pageable.getSort().getOrderFor("emailAddress");
    if (emailAddressOrder != null) {
        if (emailAddressOrder.getDirection() == Sort.Direction.ASC)
            members = memberRepo.findInProjectDefaultSortAsc(projectId, skipFullName, fullName, pageable);
        else
            members = memberRepo.findInProjectDefaultSortDesc(projectId, skipFullName, fullName, pageable);
    }
    else
        members = memberRepo.findInProject(projectId, skipFullName, fullName, pageable);
}
else
    members = memberRepo.findInProjectDefaultSortAsc(projectId, skipFullName, fullName, pageable);

看起来不是很漂亮,但应该可以吧?错了,因为 Pageable 仍然包含无效的 属性 emailAddress.

那么我该如何删除这个 属性?我尝试将其转换为 PageRequest 但即使是该实现对象也不可写。我现在所做的是:

PageRequest newPageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize());

然后我将这个新对象传递给查询。但这似乎有点容易出错,如果稍后使用其他属性扩展 PageRequest 实体怎么办,那么我的对象仍然只复制 2 个属性。这真的是我现在能做的最好的吗?

是的,别担心。你的方法没有错。 Pageable / PageRequest 是不可变的,这实际上是一个很好的做法。使用不可变 类 时,标准做法是创建具有(可能)已修改属性的副本。

另外,不要担心未来。如果 PageRequest 实体在未来得到扩展,Spring 开发人员几乎肯定会保持它不可变。构造函数/工厂方法中将有一个新参数,这将导致编译错误。当你升级一个库的版本时,得到这样的错误是最好的,这可能会发生。

编辑: 您还有一个选择:不要将 Sort 嵌入 Pageable。将它们用作两个单独的参数。第一个参数是 Pageable,没有任何排序信息。第二个参数可以是 Spring 的 Sort,但你也可以自由使用自己的数据类型,例如一些 enum.