3

我需要将分页与使用实体图的自定义查询结合使用。我的存储库如下所示:

@Repository
public interface MaintenanceRepository extends JpaRepository<Maintenance, Long>, QueryDslPredicateExecutor<Maintenance> {

  @EntityGraph(value = "Maintenance.Graph")
  @Query("select m from Maintenance m where m.detail.type.company = ?1 ")
  Page<Maintenance> findWithCompany(Company company, Pageable pageable);
}

为了比较,我使用此方法和使用findAll继承自的方法获取维护QueryDslPredicateExecutor

    ...
    Pageable pageable = new PageRequest(pageNumber, pageSize, Sort.Direction.DESC, "creationTime");
    Page<Maintenance> page = repo.findWithCompany(company, pageable);
    Page<Maintenance> page2 = repo.findAll(QMaintenance.maintenance.detail.type.company.eq(company), pageable);
    LOGGER.debug("Old: {} - {}, New: {} - {}", page.getTotalElements(), page.getContent().size(), page2.getTotalElements(), page2.getContent().size());
    ...

在数据库中有 3 个维护寄存器,当我使用页面大小为 1、2 和 50 的页面调用此方法时,我得到此日志。

[28/03/2017 14:14:36] [DEBUG] Old: 3 - 1, New: 3 - 1  //total - content
[28/03/2017 14:15:09] [DEBUG] Old: 3 - 2, New: 3 - 2
[28/03/2017 14:15:27] [DEBUG] Old: 3 - 3, New: 3 - 3

根据日志,分页工作正常,但是当我使用我的存储库方法和继承findAll方法时查询非常不同。

//Query for my repository method
Hibernate: select ... where maintenanc0_.detalle=detail1_.id and detail1_.tipo=type2_.id and type2_.compania=? order by maintenanc0_.fecha desc

//Query for inherited `findAll` method
Hibernate: select ... where maintenanc0_.detalle=detail1_.id and detail1_.tipo=type2_.id and type2_.compania=? order by maintenanc0_.fecha desc limit ?

两个日志已被剪切以显示相关信息,在第二个查询中,实体图提示尚未使用,因为我无法为其提供 Predicate 对象,但我理解这不是我的问题。

有了这个结果,我知道使用我的存储库方法(第一个查询)我没有得到真正的分页,因为 spring 正在用正确的内容大小填充列表,并且查询没有limit关键字。

对于第二个查询,我得到了一个真正的分页,因为数据库正在做这项工作。

根据 Spring Data参考,我应该能够使用自定义查询方法进行分页。

我关心的是性能,因为我不想在内存中加载太多数据,我需要在数据库级别完成真正的分页。

使用QueryDslPredicateExecutor很好,但我无法为实体图设置提示。

4

0 回答 0