关于jpa:spring-data-jpa使用native-sql进行分页查询时需要使用countQuery

62次阅读

共计 1102 个字符,预计需要花费 3 分钟才能阅读完成。

问题发现:
应用 data jpa 的 native sql 进行分页查问时,发现一个 sql grammar 语法报错,再三查看确认本人的 sql 写的没有问题,sql 大抵为

select * from (select * from table1 where) as table2 where

的一个子查问构造,
报错为

from (select *)from table1 where) as table2 where

左近有语法错误,比照发现多了一个)右括号。
最初发现是分页查问的 count 查问导致的。

题外话:在应用 spring data jpa 的 @Query 的 native sql 进行分页查问时,能够在办法最初一个参数传入 pageable 做分页查问,当然也能够在 native sql 中应用 limit offset 做分页查问,第一种形式会转换为第二种形式执行。

但分页查问不仅仅返回查问分页的数据,同样会返回符合条件的总个数,也就是 totalElements 以及 totalPages。
那么肯定会有一个 count 查问来干这个事,如果你没写 count 查问(我就没写),jpa 会本人帮你生成一个,但 jpa 生成的不肯定是你想要的,问题发现中的语法错误就是 jpa 帮咱们生成的 count 查问。
正确的是:

select count(*)from (select * from table1 where) as table2 where

生成的是:

select count(* from (select *)from table1 where) as table2 where

jpa 生成的 count 查问右括号匹配到了第二个 *,也就导致了语法错误。。。。。

拓展:
对于 count 的执行问题 jpa 有逻辑如下:
SimpleJpaRepository(crudRepository 的默认实现)下的


咱们能够看到第一张图中在做分页是传入的第三个参数就是计数查问,而在第二张图中当查问到的数据是少于 pageSize 时,也就是总数能够在以后查到的第一页算出时,是不须要去执行后续的 count 查问的,也算是个简略的优化。
官网注解的话是:

The construction of {@link Page} omits a count query if the total can be determined based on the result size and {@link Pageable}.

总结:而在应用 办法名规定 或者 qbc 进行分页查问时是不会呈现上述问题的,查问 sql 和计数 sql 都是统一生成的。而应用 natvie sql 时 jpa 会依据你写的 sql 语句改写 count(看起来只是做了一些简略的字符串匹配),于是呈现了上述问题。
在应用 native sql 进行分页查问时记得应用 countQuery

正文完
 0