问题
Spring Data JPA的一个方便功能是,通过其@Query
注释,允许您插入自定义JPA查询。
这使得您仍然能够向应用程序的使用者提供排序参数,这种灵活性是很有用的。看看下面的示例:
interface SampleRepository extends CrudRepository<Employee, Long> {
@Query("select e from Employee e where e.firstName = :firstName")
List<Employee> findCustomEmployees(String firstName, Sort sort);
}
Spring Data JPA将在提供不仅具有标准(firstName
)而且还具有自定义排序(findCustomEmployees(“Alice”,Sort.by(“lastName”))
)时将此自定义查询转换为JPA查询,成为如下完整查询:
select e
from Employee e
where e.firstName = :firstName
order by e.lastName
除此之外,Spring Data JPA还支持分页,这需要能够计算结果集的能力。
过去,随着越来越复杂的查询,我们“做正确的事情”并应用正确指向主要SELECT子句别名值的“order by”子句的能力是至少具有挑战性的。
当有子查询、case语句和其他深度查询时,将投影包装到适当的count()
函数中也很棘手!
解决方案
我们很高兴宣布发布HQL和JPQL解析器,这将使您更轻松地定制Spring Data JPA应用程序中的查询。
使用JPA和Hibernate规范,我们开发了基于ANTLR的查询解析引擎,并使用它们来更正确地应用所需的自定义。
我们不仅可以找到放置count()
函数的“正确位置”,还可以收集主要FROM
表达式的别名,从而可以检测语义情况。
使用查询分析器,更容易识别有效和无效查询。有时,我们会花费更多的时间来确定查询是否正确,然后再弄清楚如何正确处理它。
我该如何使用它?
好消息是…它会自动应用。
使用@Query
注释时,有一个关键参数:isNative
。此布尔标志允许您发信是否编写本机SQL(isNative=true
)还是JPA查询(isNative=false
默认)。
如果您具有JPA查询(isNative=false
)并且类路径上存在Hibernate,则它将使用我们的新HQL解析器。如果类路径上不存在Hibernate,则将回退到相对有限的JPQL解析器。 (受规范限制,而不是我们的实现。)
因此,您所要做的就是要么拾取Spring Data版本系列的最新快照版本(Spring Data 3.1快照版本),要么拾取Spring Boot的下一个里程碑版本。
下一步是什么?
还有更多功能要添加。例如,可能会出现更复杂的别名,例如:
select AVG(e.timeToCloseTickets) as avg
from Employee e
当您应用Sort.by(“avg”)
时,此类型的查询不应产生order by e.avg
,而应该只是order by avg
。我们正在研究添加支持的其他情况。但是有了这些查询解析器,支持这些情况变得更加容易。
我们还有一些与查询解析相关的票据积压,现在我们可以通过它们。
奖励
作为奖励,如果您想要预先检查自己的自定义查询,今天的工具就可以了。
如果您使用IntelliJ IDEA,则有一个ANTLR插件(https://plugins.jetbrains.com/plugin/7358-antlr-v4),安装后,它会让您运行任何ANTLR语法文件并进行测试。
1.安装IntelliJ IDEA的ANTLR插件。 2.克隆Spring Data JPA的源代码库。 3.找到src/main/antlr4/org/springframework/data/jpa/repository/query/Hql.g4
。 4.右键单击“开始”,然后选择“测试规则启动” 5.在左侧的框中输入查询,然后在右侧的窗格中查看AST。
(我们最近要求人们发送他们最疯狂的JPA查询之一,这是其中之一。乍一看,查询是有效的,您甚至可以放大查看更多内容。)
干杯,–Greg Turnquist
没有回复内容