如何编辑 Spring Pageable 对象?

Seb*_*oek 5 java spring hibernate jpql spring-data-jpa

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

我有一些Member具有属性的DTO emailAddress。客户端不知道,这是由来自 2 个不同实体的查询收集的信息,Account或者Invite。AMember总是具有其中之一。这工作得很好,我在 repo 中执行标准 JPA 查询并在将其转换为 DTO 之前收集所需的信息。

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

但是现在客户想要对这个emailAddress属性进行排序,麻烦就开始了。直接将 the 传递Pageable给 theRepository不起作用,因为没有 property 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);
Run Code Online (Sandbox Code Playgroud)

看起来不是很漂亮,但应该可以正常工作吗?错误,因为PageableSTILL 包含无效属性emailAddress

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

PageRequest newPageRequest = PageRequest.of(pageable.getPageNumber(), pageable.getPageSize());
Run Code Online (Sandbox Code Playgroud)

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

ygo*_*gor 6

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

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

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