Java Spring Data PageImpl是否返回大小正确的页面?
我正在尝试使用从数据库检索到的对象列表创建一个新的Java Spring Data PageImpl是否返回大小正确的页面?,java,spring,spring-mvc,spring-data,spring-data-jpa,Java,Spring,Spring Mvc,Spring Data,Spring Data Jpa,我正在尝试使用从数据库检索到的对象列表创建一个新的页面。首先,我从数据库中获取所有元素,将其转换为流,然后使用lambda过滤结果。然后我需要一个包含一定数量元素的页面,然而,实例化一个新的PageImpl似乎并没有返回正确大小的页面 这是我的密码: List<Produtos> listaFinal; Stream<Produtos> stream = produtosRepository.findAll().stream(); listaFinal = 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);
列表列表最终;
Stream-Stream=produtosRepository.findAll().Stream();
listaFinal=stream.filter(p->p.getProdNome().contains(“uio”)).collect(Collectors.toList());
long total=listaFinal.size();
页面导入=新页面导入(列表最终、可分页、总计);
以下是调试的屏幕截图:
请注意,Pageable对象中的大小设置为20,它知道需要4页来呈现70个元素,但它返回整个列表
我错过了什么
编辑回答托马斯的评论:
我了解如何使用页面只返回一部分数据。我展示的代码是我尝试使用lambda表达式过滤我的集合。我的问题是我想使用Java8的lambda通过SpringDataJPA查询数据库。我已经习惯了VB.NET和实体函数(x)
查询表达式,我想知道如何使用SpringJPA实现同样的功能
在我的存储库中,我使用
扩展了JpaRepository,querydsldpredicateexecutor
,这使我能够访问findAll(谓词,可分页)
。但是,谓词不是类型化的,因此我不能在查询中简单地使用p->p.getProdNome().contains(“uio”)
。我使用的是SQL Server和Hibernate。如果我正确理解了您的代码,那么您的目的是从数据库加载所有记录,并将它们拆分为x个存储桶,这些存储桶收集在PageImpl
中,对吗
这不是它过去的工作方式。Pageable
和Page
抽象的实际意图不是
必须查询所有数据,但只查询所需数据的“切片”
在您的情况下,您可以通过Page=repository.findAll(可分页)查询数据
并简单地返回它。
页面保存当前页面的记录以及一些附加信息,如记录总数和是否有下一页
在客户端代码中,您可以使用该信息呈现记录列表,并适当地生成下一个/上一个链接。
请注意,Page
作为结果类型的查询发出2个查询(1个用于确定查询的总计数,1个用于实际页面数据)
如果您不需要关于结果总数的信息,但仍然希望能够生成下一个链接,那么您应该
使用
Slice
作为返回类型-因为它只发出一个查询。PageImpl
不用于对列表执行任何类型的分页。您可以看到,它只是“基本页面实现”,这听起来几乎像您想要的,但它确实具有误导性
使用它是一个简单的状态保持器,用于处理对象列表,将它们分成页面。在了解了Spring数据的工作原理后,我最终在JpaRepository实现中对我的方法使用了@Query
注释来正确查询数据库并过滤结果,无需使用流,然后再转换回页面
下面是上面的代码在任何人需要示例时的外观:
@Query("select p from Produtos p where p.prodNome = ?1")
public Page<Produtos> productsListByName(String prodNome, Pageable pageable)
@Query(“从Produtos p中选择p,其中p.prodNome=?1”)
公共页面productsListByName(字符串prodNome,可分页)
我知道Spring的findBy
方法,但有时方法名很难读取,这取决于参数的数量,所以我坚持使用JPQL
通过这种方式,页面的内容将始终具有您在Spring配置中定义的最大元素量
我还使用了PageImpl
的自定义实现,我现在不在工作,也没有访问代码的权限,但我会尽可能发布它
编辑:可以找到自定义实现要扩展,a是一种方法,下面是如何:
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 page=新的PagedListHolder(列表);
page.setPageSize(10);//每页的项目数
第页。设置第页(0);//设置为第一页
//检索
page.getPageCount();//页数
page.getPageList();//表示当前页面的列表
如果您需要排序,请使用另一个带有。的方法。在应用了许多方法之后,这就是我的情况下的解决方案,它正在工作
> 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)
>int pageSize=pageable.getPageSize();
>long pageOffset=pageable.getOffset();
>长总计=pageOffset+list.size()+(list.size()==pageSize?pageSize:0);
>Page Page=新PageImpl(列表、可分页、总计)
我知道现在添加答案已经太晚了。但我也面临着同样的问题&我找到了解决的办法SimpleParepository
具有以下方法
public Page<T> findAll(Specification<T> spec, Pageable pageable) {
TypedQuery<T> query = getQuery(spec, pageable);
return pageable == null ? new PageImpl<T>(query.getResultList())
: readPage(query, getDomainClass(), pageable, spec);
}
方法getCountForQuery:
private Long getCountForQuery(Class<?> t){
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery<Long> countQuery = criteriaBuilder
.createQuery(Long.class);
countQuery.select(criteriaBuilder.count(
countQuery.from(t)));
Long count = entityManager.createQuery(countQuery)
.getSingleResult();
return count;
}
SimpleParepository
中的方法,该方法主要由findAll
内部方法使用。我用我的评论编辑了我的原始问题,因为它太长了,不能在这里写,请看!谢谢,我也面临同样的问题。我必须使用DTO映射查询的输出,以删除一些隐藏列。所以我首先得到所有结果,然后根据DTO将结果映射到新的输出。然后在新结果上使用PageImpl。但是它显示的是所有的记录,而不是页面信息。很好!我会给这一个镜头与我的工作。你能提供我的代码,你一直在使用PageImpl。我现在面临着同样的问题!代码添加。注意,在我的例子中需要这个实现,因为我处理的是REST服务,而默认实现不是w
private Long getCountForQuery(Class<?> t){
CriteriaBuilder criteriaBuilder=entityManager.getCriteriaBuilder();
CriteriaQuery<Long> countQuery = criteriaBuilder
.createQuery(Long.class);
countQuery.select(criteriaBuilder.count(
countQuery.from(t)));
Long count = entityManager.createQuery(countQuery)
.getSingleResult();
return count;
}
readPage(TypedQuery<S> query, final Class<S> domainClass, Pageable pageable,
final Specification<S> spec)