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桶,对吧?
这不是以前的工作方式。 Pageable
和Page
抽象的实际意图不是要查询所有数据,而只需要查询所需数据的“切片”。
在您的情况下,您可以通过Page
查询数据Page
并简单地返回。 页面包含当前页面的记录以及一些其他信息,例如记录总数以及是否有下一页。
在您的客户端代码中,您可以使用该信息来呈现记录列表并适当地生成下一个/上一个链接。 请注意,使用Page
作为结果类型的查询会发出2个查询(1表示查询的总计数,1表示实际页面数据)。
如果您不需要有关结果总数的信息但仍希望能够生成下一个链接,则应使用Slice
作为返回类型 – 因为它只发出1个查询。
PageImpl
不用于对列表执行任何类型的分页。 从文档中你可以看到,它只是“基本的Page
实现”,几乎听起来像你想要的,但它确实是误导。
使用PagedListHolder
是一个简单的状态持有者,用于处理对象列表,将它们分成页面。