Spring Data JPA 引入查询解析器!

工程 | Greg L. Turnquist | 2023年3月21日 | ...

问题

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);

}

如果不仅提供条件 (firstName),还通过findCustomEmployees("Alice", Sort.by("lastName"))提供自定义排序,Spring Data JPA 会将此自定义查询转换为以下完整的 JPA 查询

select e
from Employee e
where e.firstName = :firstName
order by e.lastName

最重要的是,Spring Data JPA 支持分页,这需要能够计算结果集。

过去,随着越来越复杂的查询,我们“做正确的事情”并应用正确指向主 SELECT 子句别名值的“order by”子句的能力,至少可以说是具有挑战性的。

用正确的count()函数包装投影也很棘手。想象一下,当存在子查询、case 语句和其他深度查询时,该如何处理!

解决方案

我们很高兴地宣布发布 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. 右键单击“start”并选择“Test rule start”。
  5. 在左侧的框中输入您的查询,然后在右侧的窗口窗格中查看 AST。

IntelliJ IDEA with ANTLR plugin showing a query

(我们最近要求人们提交他们最疯狂的 JPA 查询,这是其中之一。乍一看,该查询有效,您甚至可以放大以查看更多内容。)

此致,--Greg Turnquist

获取 Spring Newsletter

通过 Spring Newsletter 保持联系

订阅

领先一步

VMware 提供培训和认证,以加快您的进度。

了解更多

获得支持

Tanzu Spring在一个简单的订阅中提供对OpenJDK™、Spring和Apache Tomcat®的支持和二进制文件。

了解更多

即将举行的活动

查看 Spring 社区中所有即将举行的活动。

查看全部