和 之间的主要区别在于后者提供了不平凡的分页详细信息,例如满足查询条件的记录总数(),总页数()和下一页可用性状态(),另一方面,前者仅提供分页详细信息,例如下一页可用性状态()与其对应项相比。 当您处理具有新兴记录的巨大表时,可提供显著的性能优势。Slice
Page
getTotalElements()
getTotalPages()
hasNext()
hasNext()
Page
Slice
让我们更深入地了解这两种变体的技术实现。
static class PagedExecution extends JpaQueryExecution {
@Override
protected Object doExecute(final AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor accessor) {
Query query = repositoryQuery.createQuery(accessor);
return PageableExecutionUtils.getPage(query.getResultList(), accessor.getPageable(),
() -> count(repositoryQuery, accessor));
}
private long count(AbstractJpaQuery repositoryQuery, JpaParametersParameterAccessor accessor) {
List<?> totals = repositoryQuery.createCountQuery(accessor).getResultList();
return (totals.size() == 1 ? CONVERSION_SERVICE.convert(totals.get(0), Long.class) : totals.size());
}
}
如果您观察上面的代码片段,PagedExecution#doExecute 方法将调用 PagedExecution#count 方法,以获取满足条件的记录总数。
static class SlicedExecution extends JpaQueryExecution {
@Override
protected Object doExecute(AbstractJpaQuery query, JpaParametersParameterAccessor accessor) {
Pageable pageable = accessor.getPageable();
Query createQuery = query.createQuery(accessor);
int pageSize = 0;
if (pageable.isPaged()) {
pageSize = pageable.getPageSize();
createQuery.setMaxResults(pageSize + 1);
}
List<Object> resultList = createQuery.getResultList();
boolean hasNext = pageable.isPaged() && resultList.size() > pageSize;
return new SliceImpl<>(hasNext ? resultList.subList(0, pageSize) : resultList, pageable, hasNext);
}
}
如果您观察上面的代码片段,为了找出下一组结果是否存在(对于),该方法总是获取额外的一个element()并根据pageSize condition()跳过它。hasNext()
SlicedExecution#doExecute
createQuery.setMaxResults(pageSize + 1)
hasNext ? resultList.subList(0, pageSize) : resultList
- 应用:
-
页
当UI/GUI期望在搜索/查询本身的初始阶段显示所有结果,并带有要遍历的页码(例如,带有页码的bankStatement)时使用
-
片
当 UI/GUI 不希望在搜索/查询本身的初始阶段显示所有结果,而是打算根据滚动或下一个按钮单击事件(例如,Facebook 源搜索)显示要遍历的记录时使用