春季数据 - 为什么不可能使用本机查询进行分页

2022-09-02 11:16:56

假设我们有一个名为 的实体。可以使用命名查询查询和命名查询来查询可分页的结果,例如MyEntity@Query

 @Query(value = "select e from MyEntity e where e.enabled = true")
 Page<MyEntity> findAllEnabled(Pageable pageable);

但是,使用本机查询不可能实现相同的目的,因此

 @Query(value = "select * from my_entity where enabled = true", nativeQuery = true)
 Page<MyEntity> findAllEnabled(Pageable pageable);

不起作用。

这背后的原因是什么?是否可以使 Pageable 与本机查询一起使用?


答案 1

我不知道这是否仍然与你相关:至少在Spring Data JPA 1.9.4中,你可以指定两个查询。

给定一个存储库:

interface FoobarEntityRepository extends JpaRepository<FoobarEntity, Integer> {
    Page findFoobarsSpecialQuery(String someParameter, final Pageable pageable);
}

您可以向实体添加 2 个本机查询,一个用于查询本身,一个用于 count 语句:

@Entity
@SqlResultSetMappings({
    @SqlResultSetMapping(name = "SqlResultSetMapping.count", columns = @ColumnResult(name = "cnt"))
})
@NamedNativeQueries({
    @NamedNativeQuery(
            name = "FoobarEntity.findFoobarsSpecialQuery",
            resultClass = DailyPictureEntity.class,
            query = "Select * from foobars f where someValue = :someParameter "
    ),
    @NamedNativeQuery(
            name = "FoobarEntity.findFoobarsSpecialQuery.count",
            resultSetMapping = "SqlResultSetMapping.count",
            query = "Select count(*) as cnt from foobars f where someValue = :someParameter "
    )
})
FoobarEntity {
}

诀窍是使用后缀指定计数查询。这也适用于弹簧数据注释。.count@Query

请注意,您需要为计数查询提供 SQL 结果集映射。

这实际上很不错。


答案 2

这是描述,在春季数据jpa文档中给出(http://docs.spring.io/spring-data/jpa/docs/1.8.0.M1/reference/html/)

本机查询@Query注释允许通过将 nativeQuery 标志设置为 true 来执行本机查询。请注意,我们目前不支持对本机查询执行分页或动态排序,因为我们必须操作声明的实际查询,并且我们无法为本机 SQL 可靠地执行此操作。

JPQL抽象化了SQL实现及其提供者的细节,并使其成为ORM框架的责任来生成正确的SQL。

  1. 因此,通过使用JPQL形式的分页,Spring只需要生成正确的JPQL,它就会在ORM级别上进行解释以纠正SQL。

  2. 在使用SQL这样做时,这意味着Spring知道如何为RDBMS的绝大多数生成正确的SQL,复制ORM功能,这太大了。


推荐