• 使用Spring Data JPA 本机查询


    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

    @Repository

    public interface AuthorRepository extends CrudRepository, PagingAndSortingRepository {

        @Query(value="select * from author a where a.first_name= :firstName", nativeQuery=true)

        List getAuthorsByFirstName(String firstName);

    }

    完成此操作后,只需将存储库注入到其中一个服务中,并使用要搜索的firstName调用getAuthorsByFirstName方法。

    1

    List authors = authorRepository.getAuthorsByFirstName("Janssen");

    然后,Spring Data 的存储库实现提供所需的代码来实例化对注释中提供的语句的查询@Query。然后,它将提供的值设置为该查询的绑定参数并执行它。

    将操作写入为本机查询

    正如我在 Hibernate 性能调优在线培训中详细解释的那样,批量操作通常是更改或删除大量数据库记录的更好选择。您可以使用 JPQL、条件本机查询来实现这些操作。

    您可以使用@Query注释来定义此类 JPQL 或本机 SQL 语句。由于写入操作的执行方式与读取操作不同,因此还需要使用@Modifying注释来批注存储库方法。这是与前面讨论的本机 SQL SELECT 语句的唯一区别。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    @Repository

    public interface AuthorRepository extends CrudRepository, PagingAndSortingRepository {

        @Modifying

        @Query(value="delete from author a where a.last_name= :lastName", nativeQuery = true)

        void deleteAuthorByLastName(@Param("lastName") String lastName);

         

        @Modifying

        @Query(value="update author set last_name= :lastName where first_name = :firstName", nativeQuery=true)

        void updateAuthorByFirstName(String firstName, String lastName);

         

        ...

    }

    使用 Spring 数据 JPA 进行本机查询的限制

    使用本机查询时,需要注意 2 个限制:

    1. Spring Data JPA 和持久性提供程序不会将查询调整为数据库的特定 SQL 方言。因此,您需要确保应用程序支持的所有 RDBMS 都可以处理提供的语句。
    2. 本机查询结果的分页需要一个额外的步骤。
    3. Spring Data JPA 不支持本机 SQL 语句的动态排序。

    让我们仔细看看第 2 个和第 3 个限制。

    添加计数查询以启用分页

    使用自定义 JPQL 查询时,可以将可分页类型的参数添加到存储库方法。这将为查询结果启用分页。然后,Spring Data JPA 添加所有必需的样板代码,一次检索一页的查询结果。

    对本机查询执行相同操作需要额外的步骤。您需要提供一个计数查询,该查询返回非分页结果中包含的记录总数。一种方法是提供查询字符串作为@Query注释的countQuery属性的值。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    @Repository

    public interface AuthorRepository extends CrudRepository, PagingAndSortingRepository {

         

        @Query(value="select * from author a where a.last_name= ?1",

                countQuery = "select count(id) from author a where a.last_name= ?1",

                nativeQuery = true)

        Page getAuthorsByLastName(String lastname, Pageable page);

         

        ...

    }

    如果存储库方法引用命名本机查询,则需要将计数查询作为第二个命名查询提供,并在其名称中添加后缀 sendix.count

    1

    2

    3

    4

    5

    6

    7

    @NamedNativeQuery(name = "Author.getAuthorsByLastName",

                        query = "select * from author a where a.last_name= ?1",

                        resultClass = Author.class)

    @NamedNativeQuery(name = "Author.getAuthorsByLastName.count",

                        query = "select count(id) from author a where a.last_name= ?1")

    @Entity

    public class Author { ... }

    无动态排序

    使用 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 查询相比,它们提供了一些限制。最值得注意的是:

    1. 若要对查询结果使用分页,需要提供计数查询。您可以通过设置 @Query注释的countQuery属性来执行此操作。
    2. Spring Data JPA 不支持本机查询的动态排序。如果要按特定顺序检索查询结果,则需要在查询中包含 ORDER BY 子句。
    3. Spring Data JPA 和持久性提供程序不会将本机查询语句调整为数据库的 SQL 方言。因此,您需要确保所有受支持的 DBMS 都支持您的 SQL 语句。
  • 相关阅读:
    数据结构-复杂度(一)
    【Linux】CentOS8.4 安装docker
    TypeScript对于Duck类型和模块命名空间的应用实战
    政安晨:【Keras机器学习示例演绎】(十七)—— 用于图像分类的 RandAugment 可提高鲁棒性
    Mysql 视图
    php组件漏洞
    Jenkins Pipeline
    产品Web3D交互展示有什么优势?如何快速制作?
    C语言-调试文件
    Spire.PDF for .NET【文档操作】演示:将新的 PDF 页面插入到指定索引处的现有 PDF 中
  • 原文地址:https://blog.csdn.net/allway2/article/details/128196486