我正在尝试使用从数据库中检索的对象列表创建新的 Page
. 首先,我从DB获取所有元素,将其转换为Stream,然后使用lambda过滤结果 . 然后我需要一个具有一定数量元素的页面,但是,实例化一个新的 PageImpl
似乎不会返回一个具有正确大小的页面 .
这是我的代码:
List<Produtos> listaFinal;
Stream<Produtos> stream = produtosRepository.findAll().stream();
listaFinal = stream.filter(p -> p.getProdNome().contains("uio")).collect(Collectors.toList());
long total = listaFinal.size();
Page<Produtos> imp = new PageImpl<>(listaFinal,pageable,total);
这是调试的屏幕截图:
请注意,Pageable对象中的大小设置为20,并且它理解它需要4个页面来呈现70个元素,但它返回整个列表 .
我错过了什么?
Edit answering the comment made by Thomas:
我理解如何使用Page返回一小部分数据 . 我展示的代码是我尝试使用lambda表达式来过滤我的集合 . 对我来说问题是我想使用Java 8 's lambda to query the database via Spring Data JPA. Im used to VB.NET'和实体 function(x)
查询表达式,并想知道如何使用Spring JPA做同样的事情 .
在我的存储库中,我使用 extends JpaRepository<Produtos, Integer>, QueryDslPredicateExecutor<Produtos>
,这使我可以访问 findAll(Predicate,Pageable)
. 但是,Predicate没有输入,所以我不能在查询中使用 p -> p.getProdNome().contains("uio")
. 我正在使用SQL Server和Hibernate .
5 回答
PageImpl
无意对您的列表执行任何类型的分页 . From the docs你可以看到它只是“基本Page
实现”,几乎听起来像你想要的,但它确实是误导 .使用PagedListHolder这是一个简单的状态持有者,用于处理对象列表,将它们分成页面 .
在应用了很多方法之后,这就是我的解决方案,并且它正在运行
在了解了有关Spring Data如何工作的更多信息之后,我最终在JpaRepository实现中的方法上使用
@Query
注释来正确查询数据库并过滤结果,从而无需使用流然后转换回Page .如果有人需要一个例子,上面的代码就是这样的:
我知道Spring的
findBy
方法,但有时方法名称变得非常难以阅读,这取决于参数的数量,所以我只是坚持使用JPQL .这样做,Page的内容将始终具有Spring配置中定义的最大元素数量 .
我还使用
PageImpl
的自定义实现,我可以访问代码,但我会尽可能地发布它 .编辑:可以找到自定义实现here
要扩展stites' answer,PagedListHolder是要走的路,这里是如何:
如果需要排序,请使用另一个PagedListHolder constructor和MutableSortDefinition .
如果我理解你的代码是正确的,那么你的意图是从数据库加载所有记录,并将它们分成在_1749344中收集的x桶,对吗?
这不是以前的工作方式 .
Pageable
和Page
抽象的实际意图不是要查询所有数据,而只需查询所需的"slice"数据 .在您的情况下,您可以通过
Page<X> page = repository.findAll(pageable);
查询数据,然后返回 . 页面包含当前页面的记录以及一些其他信息,例如记录总数以及是否有下一页 .在您的客户端代码中,您可以使用该信息来呈现记录列表并适当地生成下一个/上一个链接 . 请注意,使用
Page<X>
作为结果类型的查询会发出2个查询(1表示查询的总计数,1表示实际页面数据) .如果您不需要有关结果总数的信息但仍希望能够生成下一个链接,则应使用
Slice<X>
作为返回类型 - 因为它只发出1个查询 .