如何编辑Spring Pageable对象?

时间:2018-12-11 07:24:12

标签: java spring hibernate spring-data-jpa jpql

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

我有一些DTO Member,其属性为emailAddress。客户端不知道这是由来自AccountInvite两个不同实体的查询收集的信息。 Member始终具有其中之一。 这足够好,我在仓库中执行了一个标准的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个属性。这真的是我现在能做的最好的吗?

1 个答案:

答案 0 :(得分:2)

是的,不用担心。您的方法没有错。 Pageable / PageRequest是不可变的,这实际上是一个好习惯。使用不可变类时,通常的做法是创建具有(可能是)修改后属性的副本。

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

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