Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/330.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Spring Data PageImpl是否返回大小正确的页面?_Java_Spring_Spring Mvc_Spring Data_Spring Data Jpa - Fatal编程技术网

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)