首页 文章

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

提问于
浏览
7

我正在尝试使用从数据库中检索的对象列表创建新的 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 回答

  • 4

    PageImpl 无意对您的列表执行任何类型的分页 . From the docs你可以看到它只是“基本 Page 实现”,几乎听起来像你想要的,但它确实是误导 .

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

  • 3

    在应用了很多方法之后,这就是我的解决方案,并且它正在运行

    >         int pageSize = pageable.getPageSize();
    >         long pageOffset = pageable.getOffset();
    >         long total = pageOffset + list.size() + (list.size() == pageSize ? pageSize : 0);
    >         Page<listType> page = new PageImpl<listType>(list, pageable,total)
    
  • 0

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

    如果有人需要一个例子,上面的代码就是这样的:

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

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

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

    我还使用 PageImpl 的自定义实现,我可以访问代码,但我会尽可能地发布它 .

    编辑:可以找到自定义实现here

  • 4

    要扩展stites' answerPagedListHolder是要走的路,这里是如何:

    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
    

    如果需要排序,请使用另一个PagedListHolder constructorMutableSortDefinition .

  • 3

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

    这不是以前的工作方式 . PageablePage 抽象的实际意图不是要查询所有数据,而只需查询所需的"slice"数据 .

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

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

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

相关问题