我正在尝试使用从数据库中检索的对象列表创建新的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个元素,但它返回整个列表。
我错过了什么?
编辑回答托马斯的评论:
我理解如何使用Page返回一小部分数据。我展示的代码是我尝试使用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。
答案 0 :(得分:6)
要延长stites' 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。
答案 1 :(得分:4)
在了解了有关Spring Data如何工作的更多信息后,我最终在JpaRepository实现中的方法上使用 @Override
protected void onActivityResult(int requestCode, int resultCode, Intent data) {
if (requestCode == PICK_FILE_REQUEST) {
if(data!=null){
Logv("Data","got some data");
}
}
}
注释来正确查询数据库并过滤结果,从而无需使用流然后转换回页。
如果有人需要一个例子,上面的代码将如何显示:
@Query
我知道Spring的@Query("select p from Produtos p where p.prodNome = ?1")
public Page<Produtos> productsListByName(String prodNome, Pageable pageable)
方法,但有时方法名称变得非常难以阅读,这取决于参数的数量,所以我只是坚持使用JPQL。
这样做,Page的内容将始终具有Spring配置中定义的最大元素数量。
我还使用findBy
的自定义实现,我现在不在工作,无法访问代码,但我会随时发布。
修改:可以找到自定义实施here
答案 2 :(得分:3)
如果我理解你的代码是正确的,那么你的意图是从数据库中加载所有记录,并将它们分成在PageImpl
中收集的x桶,对吗?
这不是以前的工作方式。 Pageable
和Page
抽象的实际意图不是
必须查询所有数据,但只需查询&#34;切片&#34;需要的数据。
在您的情况下,您可以通过Page<X> page = repository.findAll(pageable);
查询数据,然后返回。
页面包含当前页面的记录以及一些其他信息,例如记录总数以及是否有下一页。
在您的客户端代码中,您可以使用该信息呈现记录列表并适当地生成下一个/上一个链接。
请注意,Page<X>
作为结果类型的查询会发出2个查询(1表示查询的总计数,1表示实际页面数据)。
如果您不需要有关结果总数的信息,但仍希望能够生成下一个链接,那么您应该
使用Slice<X>
作为返回类型 - 因为它只发出1个查询。
答案 3 :(得分:3)
PageImpl
无意对您的列表执行任何类型的分页。 From the docs你可以看到它只是“基本Page
实现”,几乎听起来像你想要的,但它确实具有误导性。
使用PagedListHolder
这是一个简单的状态持有者,用于处理对象列表,将它们分成页面。
答案 4 :(得分:0)
在应用了很多方法之后,这就是我的解决方案,并且可以正常工作
> 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)
答案 5 :(得分:0)
我知道添加答案为时已晚。但是我也面临着同样的问题,并且找到了解决之道。 SimpleJpaRepository
具有方法
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);
}
,用于扩展Page<T>
时用于返回JpaRepository
。因此,我们可以在此处使用相同的功能(需要重写代码,因为Spring不会为您提供公共方法以提供完整的分页支持)。
如果您查看方法PageImpl<>(List<T> content, Pageable pageable, long total);
,则只需设置您在pageable
中提供的值即可。在这里,您将发送content
作为完整列表,但是spring并不是出于内部目的。需要用以下代码块替换Page<Produtos> imp = new PageImpl<>(listaFinal,pageable,total);
。
TypedQuery<User> query = entityManager.createQuery(criteriaQuery); // Users type can be replaced with Produtos or any other db entity.
query.setFirstResult(pageable.getOffset());
query.setMaxResults(pageable.getPageSize());
List<User> users= query.getResultList();
Page<User> result=PageableExecutionUtils.getPage(users,pageable, () -> getCountForQuery(User.class));
方法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;
}
您可以在
中找到PageableExecutionUtils.getPage
的用法
readPage(TypedQuery<S> query, final Class<S> domainClass, Pageable pageable,
final Specification<S> spec)
SimpleJpaRepository
中的方法,该方法主要由findAll
内部方法使用。