如何编辑 Spring Pageable 对象?
How to edit a Spring Pageable object?
我需要能够编辑 Pageable 对象,更具体地说是 Sorts 之一。
我有一些 DTO Member
,其中有一个 属性 emailAddress
。客户端不知道,这是通过来自 2 个不同实体的查询收集的信息,Account
或 Invite
。 Member
总是有其中之一。
这很好用,我在 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
.
我需要能够编辑 Pageable 对象,更具体地说是 Sorts 之一。
我有一些 DTO Member
,其中有一个 属性 emailAddress
。客户端不知道,这是通过来自 2 个不同实体的查询收集的信息,Account
或 Invite
。 Member
总是有其中之一。
这很好用,我在 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
.