问题发现:
应用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