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

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

I am trying to create a new Page using a list of objects retrieved from the database. First I get all the elements from the DB, convert it to a Stream and then use lambda to filter the results. Then I need a Page with a set number of elements, however, instantiating a new PageImpl doesn't seem to return a page with the correct size.

这是我的代码:

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 个元素,但它会返回整个列表.

Note the size in the Pageable object is set to 20 and it understands that it needs 4 pages to render the 70 elements, but it returns the whole list.

我错过了什么?

编辑回答托马斯的评论:

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

I understand how to use Page to return just a slice of the data. The code I showed was my attempt to use a lambda expression to filter my collection. The problem for me is I want to use Java 8's lambda to query the database via Spring Data JPA. Im used to VB.NET's and Entity function(x) query expressions and was wondering how to do the same with Spring JPA.

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

In my repository, Im using extends JpaRepository<Produtos, Integer>, QueryDslPredicateExecutor<Produtos> which gives me access to findAll(Predicate,Pageable). However, the Predicate is not typed so I cant simply use p -> p.getProdNome().contains("uio") in the query. I'm using SQL Server and Hibernate.

推荐答案

在详细了解 Spring Data 的工作原理后,我最终在 JpaRepository 实现中的方法上使用 @Query 注释来正确查询对结果进行 DB 和过滤,无需使用流然后再转换回 Page.

After learning more about how Spring Data works I ended up using @Query annotations on my methods inside the JpaRepository implementations to properly query the DB and filter the results, eliminating the need to use a stream and then convert back to Page.

如果有人需要示例,以下是上述代码的外观:

Here's how the code above would look in case anyone needs an example:

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

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

Im aware of Spring's findBy methods but sometimes the method names become really difficult to read depending on the amount of parameters so I just stuck to JPQL.

这样做,页面的内容将始终包含您在 Spring 配置中定义的最大数量的元素.

Doing it this way the Page's content will always have up to the maximum amount of elements defined by you in the Spring configuration.

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

I also use a custom implementation of PageImpl, I'm not at work right now and don't have access to the code, but I'll post it whenever I can.

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

相关文章