繁体   English   中英

Spring JPA 不能与 Top 和 Pageable 一起使用

[英]Spring JPA doesn't work with Top and Pageable together

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

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

该方法还支持Pageable给结果分页。 但是,返回的结果不尊重可分页大小,并且非常混乱。 例如,当总共有 5 个实体时

myEntityRepository.findTop3By(PageRequest.of(0, 9))
// page 0 and size 9, got top 3 entities
// (good)

myEntityRepository.findTop3By(PageRequest.of(0, 4))
// page 0 and size 4, still got top 3 entities
// (good)

myEntityRepository.findTop3By(PageRequest.of(0, 3))
// page 0 and size 3, still got top 3 entities, however, returned TotalElements is 5
// (partial, expected TotalElements is 3 so that there is no next page)

myEntityRepository.findTop3By(PageRequest.of(1, 3))
// page 1 and size 3, got the 4th and 5th entities, returned TotalElements is 5 
// (wrong, expected no entities)

myEntityRepository.findTop3By(PageRequest.of(0, 2))
// page 0 and size 2, still got top 3 entities, returned TotalElements is 5
// (wrong, does not respect the page size, expected only the 1st and 2nd entities)

myEntityRepository.findTop3By(PageRequest.of(1, 2))
// page 1 and size 2, got 3rd, 4th and 5th entities, returned TotalElements is 5
// (wrong, expected only the 3rd entity)

你如何解决这个问题以获得预期的结果?

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

public interface MyEntityRepository extends 
 PagingAndSortingRepository<MyEntity, Integer> {

    List<MyEntity> findAllByColumnName(String ColumnName, 
                                       Pageable pageable);
}

然后你必须创建一个pageRequest

for(int pageCounter= 0; pageCounter < 100; ++i)
       Pageable PageRequestwithTopthree =
               PageRequest.of(pageCounter, 3, sort.by("column_name").descending());
}

编辑

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

Pageable PageRequestwithTopthree =
              PageRequest.of(pageCounter, pageSize, 
                              sort.by("column_name").descending());

您可能可以按如下方式定义一个方法(查找所有行,然后对它们进行分页):

List<Foo> findAllByOrderBySomethingAsc(Pageable pageable)

您应该以这种方式在服务层上配置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;
}

Class PageRequest 的构造函数如下

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

我们倾向于通过您想要的某些规则来订购“排序”。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM