假设我们有一个名为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使用本机查询?
答案 0 :(得分:31)
我不知道这是否仍与您相关:至少在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
的计数查询。这也适用于Spring Data @Query
注释。
请注意,您需要为计数查询提供SQL结果集映射。
这实际上很不错。
答案 1 :(得分:11)
这是春季数据jpa文档(http://docs.spring.io/spring-data/jpa/docs/1.8.0.M1/reference/html/)
中给出的描述本机查询@Query注释允许执行本机查询 通过将nativeQuery标志设置为true。请注意,我们目前没有 支持对本机查询执行分页或动态排序 因为我们必须操纵声明的实际查询,我们不能这样做 这对于原生SQL来说是可靠的。
JPQL抽象SQL实现及其提供者细节,并使ORM框架负责生成正确的SQL。
因此,通过在JPQL表单中使用Pagination,Spring只需生成正确的JPQL,它将在ORM级别上进行解释以纠正SQL。
使用SQL执行此操作时,意味着Spring知道如何为大量RDBMS生成正确的SQL,复制ORM功能,这是一个过多的开销。
答案 2 :(得分:6)
有一种方法可以将Pageable与具有Spring数据的SpEL容量的本机查询一起使用,提到here。
您可以在this repository中找到一个示例。
/**
* @see DATAJPA-564
*/
@Query(
value = "select * from (select rownum() as RN, u.* from SD_User u) where RN between ?#{ #pageable.offset -1} and ?#{#pageable.offset + #pageable.pageSize}",
countQuery = "select count(u.id) from SD_User u", nativeQuery = true)
Page<User> findUsersInNativeQueryWithPagination(Pageable pageable);
如果from
子句或您的本机查询中存在子查询并且您希望对其应用动态排序,则sort functionnality将无法正常工作。可以这样做的方法是在where
子句中移动子查询
如果" order by "
中有Sort
个对象,则Spring数据会附加到您的请求Pageable
的结束。 (使用Spring数据1.10.3)
更好的方法是尽可能在jpql中转换本机查询。