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

dub*_*nzi 10 java spring spring-mvc spring-data spring-data-jpa

我正在尝试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);
Run Code Online (Sandbox Code Playgroud)

这是调试的屏幕截图:

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

我错过了什么?

编辑回答托马斯的评论:

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

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

dub*_*nzi 7

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

如果有人需要示例,上面的代码将如下所示:

@Query("select p from Produtos p where p.prodNome = ?1")
public Page<Produtos> productsListByName(String prodNome, Pageable pageable)
Run Code Online (Sandbox Code Playgroud)

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

通过这种方式,页面的内容将始终具有您在 Spring 配置中定义的最大数量的元素。

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

编辑:自定义实现可以在这里找到


Wil*_*zel 7

要扩展站点的答案,可以使用PagedListHolder,以下是方法:

List<String> 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
Run Code Online (Sandbox Code Playgroud)

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


sti*_*tes 6

PageImpl不打算对您的列表进行任何类型的分页。从文档中您可以看到它只是“基本Page实现”,听起来几乎就像您想要的那样,但它确实具有误导性。

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