Spring Data PageImpl没有返回正确大小的页面?
我正尝试使用从数据库检索到的对象列表创建新的Page
。首先,我从数据库中获取所有元素,将其转换为Stream,然后使用lambda筛选结果。然后,我需要一个带有一组元素的页面,但是,实例化一个新的PageImpl
似乎没有返回具有正确大小的页面。Spring Data 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);
下面是调试截图:
注意在可分页对象的大小设置为20,它知道它需要4页渲染70个元素,但它返回整个列表。
我错过了什么?
编辑回答托马斯提出的意见:
我知道如何使用页面返回只是一个数据的切片。我展示的代码是我尝试使用lambda表达式来过滤我的集合。对我来说问题是我想用Java 8的lambda来通过Spring Data JPA查询数据库。我习惯VB.NET和实体function(x)
查询表达式,并想知道如何做到这一点与Spring JPA。
在我的仓库,进出口使用extends JpaRepository<Produtos, Integer>, QueryDslPredicateExecutor<Produtos>
这使我获得findAll(Predicate,Pageable)
。但是,谓词不是输入的,所以我不能在查询中简单地使用p -> p.getProdNome().contains("uio")
。我正在使用SQL Server和Hibernate。
在了解了有关Spring Data如何工作的更多信息之后,我最终在我的JpaRepository实现内部的方法上使用了@Query
注释,以正确查询数据库并筛选结果,从而消除了使用流然后转换回页面的需要。
下面是上面的代码看起来的情况下,任何人都需要一个例子:
@Query("select p from Produtos p where p.prodNome = ?1")
public Page<Produtos> productsListByName(String prodNome, Pageable pageable)
林意识到Spring的findBy
方法,但有时该方法的名字变成真的很难根据参数的量,所以我只需要读取坚持JPQL。
这样做,页面的内容总是会达到您在Spring配置中定义的最大元素数量。
我还使用了一个自定义实现PageImpl
,我现在不在工作,无法访问代码,但我会尽可能地发布它。
编辑:自定义实现可以发现here
如果我理解您的代码正确的,那么你的意图是加载数据库中的所有记录,并把它们分割成被收集在PageImpl
X水桶,对不对?
那不是它以前的工作方式。在Pageable
和Page
抽象的真实意图是不具有查询所有数据,但所需要的数据只是“切片” 。
在你的情况,你可以通过Page<X> page = repository.findAll(pageable);
查询数据并简单地返回。 页面包含当前页面的记录以及一些附加信息,例如记录总数和是否有下一页。
在客户端代码,你可以使用这些信息来呈现的记录,并适当地产生下一个/上链接的列表。 请注意,结果类型为Page<X>
的查询发出2个查询(1确定查询的总计数,1确定实际页面数据)。
如果您不需要关于结果总数的信息,但仍然希望能够生成下一个链接,则应该使用 作为返回类型 - 因为它只发出1个查询。
我编辑了我的原始问题与我的评论,因为它太长了写在这里,请看看请!谢谢。 – dubonzi 2014-11-04 19:05:11
我面临同样的问题。我必须使用DTO来映射查询的输出以删除一些隐藏的列。所以我首先得到所有的结果,然后根据DTO将结果映射到新的输出。然后对新结果使用PageImpl。但它显示所有记录而不是分页信息。 – 2015-07-01 17:04:54
PageImpl
不打算执行任何种类列表的分页的。 From the docs你可以看到它只是“基本的Page
实现”,它几乎听起来像你想要的,但它确实是误导人的。
使用PagedListHolder
这是一个简单的状态持有人处理对象列表,将它们分离成页面。
要延长stite's answer,一个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
如果需要排序,使用另一个PagedListHolder constructor与MutableSortDefinition 。
不错!我会用我正在做的事情给我一个机会。 – stites 2015-10-04 03:31:18
您可以向我提供您用于PageImpl的代码吗?我现在面临同样的问题! – user3127109 2016-06-15 10:10:09
已添加代码。请注意,在我的情况下需要执行此实现,因为我正在处理REST服务,并且默认实现对我来说不起作用,在您的情况下可能会有所不同。 – dubonzi 2016-06-23 14:11:24