简体   繁体   English

Spring 数据 JPA 分页无计数查询

[英]Spring Data JPA Pagination without count query

According to Spring docs https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories.special-parameters returning with List should not issue count query.根据 Spring docs https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repositories List发出计数查询。

But with my spring it goes kinda strange.但是我的 spring 有点奇怪。

When running page request with page 1 it works without count query which i suppose is right.当使用第1页运行页面请求时,它可以在没有计数查询的情况下工作,我认为这是正确的。

请求第 1 页

But when I invoke repository with page 2 (or above) suddenly it does a count query after select query which I didn't expect.但是,当我使用第2页(或更高版本)调用存储库时,它突然在 select 查询之后进行计数查询,这是我没想到的。

要求第 2 页或以上

Is there any way that I could make count query not issued with using Pageable?有什么方法可以使计数查询不使用 Pageable 发出

Repository and service code for what i did.我所做的存储库和服务代码。

@Repository
public interface ArticleRepository extends CrudRepository<Article, Long> {
  // Slice was also tested and did issue count query from page 2
  List<Article> findAll(Pageable pageable);
} 

@Service
public class ArticleService {
  private final ArticleRepository articleRepository;

  @Autowired
  public ArticleService(
      ArticleRepository articleRepository) {
    this.articleRepository = articleRepository;
  }

  public List<Article> getArticles(int page) {
    PageRequest pageRequest = PageRequest.of(page, 50, Sort.by("createdAt").descending());
    return articleRepository.findAll(pageRequest);
  }
}

If you need to extend CrudRepository, then you will be able to define method with Slice in your repository:如果您需要扩展 CrudRepository,那么您将能够在您的存储库中使用Slice定义方法:

Slice<Article> findAll(Pageable pageable);

I think that other option is change the super interface to PagingAndSortingRepository .我认为另一个选项是将超级接口更改为PagingAndSortingRepository It can solve the use of List on the return.它可以解决使用List就返回的问题。

interface ArticleRepository extends PagingAndSortingRepository<Article, Long> {
    List<Article> findAll(Pageable pageable);
}
  1. you can compose PagingAndSortingRepository and CrudRepository as they both are interfaces or use JpaRepository instead.您可以组合 PagingAndSortingRepository 和 CrudRepository 因为它们都是接口或使用 JpaRepository 代替。
  2. you can write your own count query by setting it into @Query annotation.您可以通过将其设置为 @Query 注释来编写自己的计数查询。

in source code for public Page<T> findAll(Pageable pageable) there is totalSupplier which executes count query to get total number.public Page<T> findAll(Pageable pageable)的源代码中,有totalSupplier执行计数查询以获取总数。

if (content.size() != 0 && pageable.getPageSize() > content.size()) {
    return new PageImpl<>(content, pageable, pageable.getOffset() + content.size());
}
return new PageImpl<>(content, pageable, totalSupplier.getAsLong());

So you cannot avoid it with default repository method.因此,您无法使用默认存储库方法来避免它。 Specify you own jpa method or declare query annotation under PagingAndSortingRepository class.指定您自己的 jpa 方法或在PagingAndSortingRepository class 下声明查询注释。

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

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