Spring Data JPA支持从数据库中检索数据的各种方法。有些非常易于使用,例如派生查询。其他方法提供了极大的灵活性,使您能够以各种方式读取和转换数据,例如自定义查询。本机查询是第二类的极端。它们是读取数据最灵活、最强大的选项。
正如我在上一篇关于JPA 中本机查询的文章中所解释的那样,它们使您可以访问数据库支持的所有功能。这使得它们非常适合需要复杂查询来提取所需信息的所有用例。当然,如果您将本机查询与 Spring Data JPA 一起使用,情况也是如此,因为您在内部使用相同的机制。Spring Data JPA 只是使本机查询的定义和执行变得更容易一些。
内容[隐藏]
使用纯 JPA 或休眠时,定义和执行本机查询需要多个步骤。Spring Data 的@Query注释删除了所有样板代码。我们已经在上一篇文章中使用了该注释来定义自定义 JPQL 查询。
定义本机查询时,使用 @Query 注释存储库方法,将其nativeQuery属性设置为true,并提供 SQL 语句作为值。如以下代码片段所示,您可以像在自定义 JPQL 查询中一样使用绑定参数。
1 2 3 4 5 6 7 8 |
|
完成此操作后,只需将存储库注入到其中一个服务中,并使用要搜索的firstName调用getAuthorsByFirstName方法。
1 |
|
然后,Spring Data 的存储库实现提供所需的代码来实例化对注释中提供的语句的查询@Query。然后,它将提供的值设置为该查询的绑定参数并执行它。
正如我在 Hibernate 性能调优在线培训中详细解释的那样,批量操作通常是更改或删除大量数据库记录的更好选择。您可以使用 JPQL、条件或本机查询来实现这些操作。
您可以使用@Query注释来定义此类 JPQL 或本机 SQL 语句。由于写入操作的执行方式与读取操作不同,因此还需要使用@Modifying注释来批注存储库方法。这是与前面讨论的本机 SQL SELECT 语句的唯一区别。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
|
使用本机查询时,需要注意 2 个限制:
让我们仔细看看第 2 个和第 3 个限制。
使用自定义 JPQL 查询时,可以将可分页类型的参数添加到存储库方法。这将为查询结果启用分页。然后,Spring Data JPA 添加所有必需的样板代码,一次检索一页的查询结果。
对本机查询执行相同操作需要额外的步骤。您需要提供一个计数查询,该查询返回非分页结果中包含的记录总数。一种方法是提供查询字符串作为@Query注释的countQuery属性的值。
1 2 3 4 5 6 7 8 9 10 |
|
如果存储库方法引用命名本机查询,则需要将计数查询作为第二个命名查询提供,并在其名称中添加后缀 sendix.count。
1 2 3 4 5 6 7 |
|
使用 JPQL 查询时,可以将类型为 Sort的参数添加到存储库方法中。这使您能够在运行时定义排序条件。然后,Spring Data JPA 根据提供的参数值生成所需的 ORDER BY 子句。
不幸的是,Spring Data JPA 不支持本机查询的此功能。这样做需要 Spring Data 分析提供的语句,并以特定于数据库的方言生成 ORDER BY 子句。这将是一个非常复杂的操作,目前不受Spring Data JPA的支持。
当然,您可以将自己的 ORDER BY 子句添加到查询中。但这限制了每个查询只能进行一个特定的排序。如果需要支持多个存储库,使用复合存储库通常是更好的方法。然后,您可以使用 JPA 的条件 API 实现自己的查询方法,并根据提供的输入参数指定 ORDER BY 子句。
本机查询是实现读取操作的最强大、最灵活的方法。它们使您能够使用数据库支持的所有功能,并且 Spring Data JPA 处理几乎所有必需的样板代码。
但是使用它们比派生查询需要付出更多的努力,并且与自定义 JPQL 查询相比,它们提供了一些限制。最值得注意的是: