Java Spring JPA不能同时使用Top和Pageable

Java Spring JPA不能同时使用Top和Pageable,java,spring,jpa,jpql,Java,Spring,Jpa,Jpql,我有一个带有方法名查询的存储库,用于返回前3个实体,例如 @Repository public interface MyEntityRepository extends PagingAndSortingRepository<MyEntity, Integer> { Page<MyEntity> findTop3By(Pageable pageable); } 如何解决此问题以获得预期的结果?您可以定义一种方法,如下所示:查找所有行,然后对它们进行分页: List

我有一个带有方法名查询的存储库,用于返回前3个实体,例如

@Repository
public interface MyEntityRepository extends PagingAndSortingRepository<MyEntity, Integer> {
    Page<MyEntity> findTop3By(Pageable pageable);
}

如何解决此问题以获得预期的结果?

您可以定义一种方法,如下所示:查找所有行,然后对它们进行分页:

List<Foo> findAllByOrderBySomethingAsc(Pageable pageable)

如果我的理解是正确的,那么您需要对存储库查询进行分页,并对响应进行排序。在这种情况下,存储库应该扩展PagingAndSortingRepository

编辑

如果您有不同的页面大小,请在pageRequest中进行更改

Pageable PageRequestwithTopthree =
              PageRequest.of(pageCounter, pageSize, 
                              sort.by("column_name").descending());
您应该以这种方式在服务层上配置Pageable

public Page<MyEntity> getTop3Page(int page, int size) {
    int topElementsNumber = 3;
    if(size > topElementsNumber) {
        size = topElementsNumber;
    }  
    
    List<MyEntity> content = getPageContent(page, size, topElementsNumber);
    return new PageImpl<>(content, pageable, topElementsNumber);
}

private List<MyEntity> getPageContent(int page, int size, int topElementsNumber) {
    int lastPage = getLastPage(size, topElementsNumber);

    Pageable pageable = PageRequest.of(page, size);
    if(page > lastPage) {
        return Collections.emptyList();
    }

    Page<MyEntity> page = repository.findAll(pageable);

    int pageLastElementNumber = (page + 1) * size;
    if(pageLastElementNumber > topElementsNumber) {
        int sublistSize = size - (pageLastElementNumber - topElementsNumber);
        return page.getContent().subList(0, sublistSize);
    } 
    
    return page.getContent();
}

private int getLastPage(int size, int topElementsNumber) {
    int lastPage = (topElementsNumber / size) - 1;
    if(topElementsNumber % size > 0) {
        lastPage++;
    }

    return lastPage;
}

类PageRequest的构造函数,如下所示

protected PageRequest(int page, int size, Sort sort)


我们倾向于通过一个“sort”来按照您想要的规则进行订购。

我认为您应该同时使用orderby和pageable,没有必要将top和pageable一起使用。您能告诉我们为什么需要这样的查询吗?另外,我很好奇hibernate生成的真实查询是如何生成的,您是否也可以共享这些查询?@Shawrup是的,它需要控制页面大小并只显示顶部results@Shawrup这只是选择。。。从我的实体限制?Top和Pageale将使用相同的构造限制?或行数,具体取决于数据库。所以这显然是行不通的。Top3已经限制了结果的数量,如果您只想进行排序,只需在方法中添加Sort而不是Pageable。您不能这样做,因为从SQL的角度来看,它们都使用相同的机制。在这两种情况下,生成的查询都类似于。对于findTop10查询方法,请从您的_表限制10中选择*,如果是可分页的,则将从您的_表限制0,10中选择*,以获得第一页。因此,它们最终是相同的机制。因此,如果您想限制总结果,您必须检查页面以不允许更多结果,并且您必须在控制器/服务中通过验证您的输入来执行此操作。嗯,顶部在哪里?您可以将pageSize设置为3,然后只显示前3,如果您想要下一页,请输入页码。但是如果我的页面大小仅为2,我能否获得第0页的第1页和第2页以及第1页的第3页?但是如果我的页面大小仅为2,我能否获得第0页的第1页和第2页以及第1页的第3页?是的,请参阅编辑。在PageRequest中传递适当的pageSize我知道,这就是我所做的,我在问题中表明这不起作用。你能分享你的存储库代码吗?更新了存储库代码如果我想要大小为2,那么在第2页上,page=1,size=2,它还会返回第4个实体,但是我只希望第二页的第三页。我已经编辑了答案。好的,我可以看到你在这里想做什么。您仍然检索完整大小的结果,但如果超过3,则删除额外的实体。这可能对其他人有用,但我认为效率不高。要创建更合适的解决方案,您需要自定义存储库。它可以是一个Criteria api查询,子查询位于WHERE-WHERE myEntity.id insubquery类排序文档位于此链接中是的,谢谢。但这里不需要这样的分类。
Pageable PageRequestwithTopthree =
              PageRequest.of(pageCounter, pageSize, 
                              sort.by("column_name").descending());
public Page<MyEntity> getTop3Page(int page, int size) {
    int topElementsNumber = 3;
    if(size > topElementsNumber) {
        size = topElementsNumber;
    }  
    
    List<MyEntity> content = getPageContent(page, size, topElementsNumber);
    return new PageImpl<>(content, pageable, topElementsNumber);
}

private List<MyEntity> getPageContent(int page, int size, int topElementsNumber) {
    int lastPage = getLastPage(size, topElementsNumber);

    Pageable pageable = PageRequest.of(page, size);
    if(page > lastPage) {
        return Collections.emptyList();
    }

    Page<MyEntity> page = repository.findAll(pageable);

    int pageLastElementNumber = (page + 1) * size;
    if(pageLastElementNumber > topElementsNumber) {
        int sublistSize = size - (pageLastElementNumber - topElementsNumber);
        return page.getContent().subList(0, sublistSize);
    } 
    
    return page.getContent();
}

private int getLastPage(int size, int topElementsNumber) {
    int lastPage = (topElementsNumber / size) - 1;
    if(topElementsNumber % size > 0) {
        lastPage++;
    }

    return lastPage;
}
protected PageRequest(int page, int size, Sort sort)