Spring Data PageImpl没有返回正确大小的页面?

我正在尝试使用从数据库中检索的对象列表创建一个新Page 。 首先,我从DB获取所有元素,将其转换为Stream,然后使用lambda过滤结果。 然后我需要一个具有一定数量元素的页面,但是,实例化一个新的PageImpl似乎不会返回一个具有正确大小的页面。

这是我的代码:

 List listaFinal; Stream stream = produtosRepository.findAll().stream(); listaFinal = stream.filter(p -> p.getProdNome().contains("uio")).collect(Collectors.toList()); long total = listaFinal.size(); Page imp = new PageImpl(listaFinal,pageable,total); 

这是调试的屏幕截图:

请注意,Pageable对象中的大小设置为20,并且它理解它需要4个页面来呈现70个元素,但它返回整个列表。

我错过了什么?

编辑回答托马斯的评论:

我理解如何使用Page返回一小部分数据。 我展示的代码是我尝试使用lambda表达式来过滤我的集合。 对我来说问题是我想使用Java 8的lambda通过Spring Data JPA查询数据库。 我习惯了VB.NET和Entity function(x)查询表达式,并想知道如何使用Spring JPA做同样的事情。

在我的存储库中,Im使用extends JpaRepository, QueryDslPredicateExecutor ,这使我可以访问findAll(Predicate,Pageable) 。 但是,Predicate没有输入,所以我不能简单地在查询中使用p -> p.getProdNome().contains("uio") 。 我正在使用SQL Server和Hibernate。

在了解了Spring Data如何工作的更多信息之后,我最终在JpaRepository实现中的方法上使用@Query注释来正确查询数据库并过滤结果,从而无需使用流然后转换回Page。

以下是上述代码在任何人需要示例的情况下的外观:

 @Query("select p from Produtos p where p.prodNome = ?1") public Page productsListByName(String prodNome, Pageable pageable) 

我知道Spring的findBy方法,但有时根据参数的数量,方法名称变得非常难以阅读,所以我只是坚持使用JPQL。

这样做,Page的内容将始终具有Spring配置中定义的最大元素数量。

我也使用PageImpl的自定义实现,我现在没有工作,也无法访问代码,但我会尽可能地发布它。

编辑:可在此处找到自定义实施

为了扩展stites的答案 ,可以使用PagedListHolder ,方法如下:

 List list = // ... // Creation PagedListHolder page = new PagedListHolder(list); page.setPageSize(10); // number of items per page page.setPage(0); // set to first page // Retrieval page.getPageCount(); // number of pages page.getPageList(); // a List which represents the current page 

如果需要排序,请使用另一个带有MutableSortDefinition的 PagedListHolder构造 函数 。

如果我理解你的代码是正确的,那么你的意图是从数据库中加载所有记录,并将它们分成在PageImpl中收集的x桶,对吧?

这不是以前的工作方式。 PageablePage抽象的实际意图不是要查询所有数据,而只需要查询所需数据的“切片”。

在您的情况下,您可以通过Page page = repository.findAll(pageable);查询数据Page page = repository.findAll(pageable); 并简单地返回。 页面包含当前页面的记录以及一些其他信息,例如记录总数以及是否有下一页。

在您的客户端代码中,您可以使用该信息来呈现记录列表并适当地生成下一个/上一个链接。 请注意,使用Page作为结果类型的查询会发出2个查询(1表示查询的总计数,1表示实际页面数据)。

如果您不需要有关结果总数的信息但仍希望能够生成下一个链接,则应使用Slice作为返回类型 – 因为它只发出1个查询。

PageImpl不用于对列表执行任何类型的分页。 从文档中你可以看到,它只是“基本的Page实现”,几乎听起来像你想要的,但它确实是误导。

使用PagedListHolder是一个简单的状态持有者,用于处理对象列表,将它们分成页面。