• Spring JPA 查询创建


    Spring JPA 查询创建

    这是JPA内容的核心部分,可以收藏用作参阅文档。

    1. 查询转化和关键字

    例:一个JPA查询的转化

    public interface UserRepository extends Repository<User, Long> {
    
      List<User> findByEmailAddressAndLastname(String emailAddress, String lastname);
    }
    

    我们使用JPA 标准API创建一个查询,但从本质上讲,这将转换为以下查询:select u from User u where u.emailAddress = ?1 and u.lastname = ?2,Spring Data JPA执行属性检查并遍历嵌套属性,如属性表达式中所述。

    下表描述了JPA支持的关键字,以及包含该关键字的方法可以转换成什么查询语句:

    表:查询关键字及对应查询语句

    关键字 样例 JPQL片段(转化的查询语句)
    And findByLastnameAndFirstname … where x.lastname = ?1 and x.firstname = ?2
    Or findByLastnameOrFirstname … where x.lastname = ?1 or x.firstname = ?2
    Is, Equals findByFirstname,findByFirstnameIs,findByFirstnameEquals … where x.firstname = ?1
    Between findByStartDateBetween … where x.startDate between ?1 and ?2
    LessThan findByAgeLessThan … where x.age < ?1
    LessThanEqual findByAgeLessThanEqual … where x.age <= ?1
    GreaterThan findByAgeGreaterThan … where x.age > ?1
    GreaterThanEqual findByAgeGreaterThanEqual … where x.age >= ?1
    After findByStartDateAfter … where x.startDate > ?1
    Before findByStartDateBefore … where x.startDate < ?1
    IsNull, Null findByAge(Is)Null … where x.age is null
    IsNotNull, NotNull findByAge(Is)NotNull … where x.age not null
    Like findByFirstnameLike … where x.firstname like ?1
    NotLike findByFirstnameNotLike … where x.firstname not like ?1
    StartingWith findByFirstnameStartingWith … where x.firstname like ?1 (参数绑定附加 %)
    EndingWith findByFirstnameEndingWith … where x.firstname like ?1 (参数绑定附加 %)
    Containing findByFirstnameContaining … where x.firstname like ?1 (参数绑定附加 %)
    OrderBy findByAgeOrderByLastnameDesc … where x.age = ?1 order by x.lastname desc
    Not findByLastnameNot … where x.lastname <> ?1
    In findByAgeIn(Collection<Age> ages) … where x.age in ?1
    NotIn findByAgeNotIn(Collection<Age> ages) … where x.age not in ?1
    True findByActiveTrue() … where x.active = true
    False findByActiveFalse() … where x.active = false
    IgnoreCase findByFirstnameIgnoreCase … where UPPER(x.firstame) = UPPER(?1)

    InNotIn也接受集合的任何子类以及数组作为一个参数或可变参数。对于相同逻辑运算符的其他语法版本,请检查存储库查询关键字。

    2. 使用@Query 自定义查询

    ​ 使用自命名查询声明实体的查询是一种有效的方法,该方法适用于少量查询。由于查询本身绑定到执行它们的Java方法上,实际上可以通过使用Spring Data JPA @Query注释直接绑定,而不用将它们注释到域类。这将域类从特定于持久性的信息中解放出来,并将查询合并到该存储库接口:

    ​ 注释@Query查询优先于使用@NamedQuery定义的查询和在orm.xml中声明的自命名查询。

    例:使用@Query在查询方法上声明查询

    public interface UserRepository extends JpaRepository<User, Long> {
    
      @Query("select u from User u where u.emailAddress = ?1")
      User findByEmailAddress(String emailAddress);
    }
    

    3. 使用高级LIKE表达式

    ​ 使用@Query创建的自命名查询的查询执行机制允许在查询定义中定义高级LIKE表达式,如下面的示例所示:

    例:@Query中定义的LIKE表达式

    public interface UserRepository extends JpaRepository<User, Long> {
    
      @Query("select u from User u where u.firstname like %?1")
      List<User> findByFirstnameEndsWith(String firstname);
    }
    

    ​ 在前面的示例中,识别了LIKE的分隔符字符(%),并将查询转换为有效的JPQL查询(移除%)。在执行查询时,传递给方法调用的参数将使用之前识别的LIKE模式进行扩充。

    4. 使用原生查询

    ​ 将nativeQuery标志设置为true, @Query注释允许运行原生查询,如下面的示例所示:

    例:使用@Query在查询方法上声明一个原生查询

    public interface UserRepository extends JpaRepository<User, Long> {
    
      @Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)
      User findByEmailAddress(String emailAddress);
    }
    

    Spring Data JPA目前不支持原生查询的动态排序,因为它必须操作声明的实际查询,而这对本地SQL来说是不可靠的。但是,您可以通过自己指定count查询来对本机查询的结果进行分页,如下面的示例所示:

    例:通过使用@Query在查询方法上声明用于分页的本机计数查询

    public interface UserRepository extends JpaRepository<User, Long> {
    
      @Query(value = "SELECT * FROM USERS WHERE LASTNAME = ?1",
        countQuery = "SELECT count(*) FROM USERS WHERE LASTNAME = ?1",
        nativeQuery = true)
      Page<User> findByLastname(String lastname, Pageable pageable);
    }
    

    5.使用Sort

    ​ 我们可以通过PageRequestSort直接完成排序,SortOrder实例中实际使用的属性需要与您的域模型(持久化模型)匹配。这意味着它们需要解析为查询中使用的属性或别名。JPQL将其定义为状态字段路径表达式。

    使用任何不可引用的路径表达式都会导致异常。

    ​ 但是,使用Sort@Query可以让您插入包含Order BY子句在内的函数非路径检查的Order实例,您可以使用JpaSort。添加可能不安全的排序。

    例:使用SortJpaSort

    public interface UserRepository extends JpaRepository<User, Long> {
    
      @Query("select u from User u where u.lastname like ?1%")
      List<User> findByAndSort(String lastname, Sort sort);
    
      @Query("select u.id, LENGTH(u.firstname) as fn_len from User u where u.lastname like ?1%")
      List<Object[]> findByAsArrayAndSort(String lastname, Sort sort);
    }
    
    repo.findByAndSort("lannister", new Sort("firstname"));               //在域模型中指向属性的有效排序表达式
    repo.findByAndSort("stark", new Sort("LENGTH(firstname)"));           //包含函数调用的无效排序。Thows 异常
    repo.findByAndSort("targaryen", JpaSort.unsafe("LENGTH(firstname)")); //包含显式不安全顺序的有效排序。
    repo.findByAsArrayAndSort("bolton", new Sort("fn_len"));              //指向别名函数的有效排序表达式。
    

    6.使用(自)命名参数

    ​ 默认情况下,Spring Data JPA使用基于位置的参数绑定,如上面的所有示例所述,即参数和?的位置一一顺序对应。这使得查询方法在重构参数位置时容易出错。要解决这个问题,可以使用@Param注释为方法参数提供一个具体名称,并在查询中绑定该名称,如下面的示例所示:

    例:使用命名参数

    public interface UserRepository extends JpaRepository<User, Long> {
    
      @Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")
      User findByLastnameOrFirstname(@Param("lastname") String lastname,
                                     @Param("firstname") String firstname);
    }
    

    这样子就不需要再保证位置的一一对应了,只需要保证名称的对应即可,方法参数根据它们在定义的查询中的顺序进行切换

    参考文档

    1.翻译:【JPA Query Methods】


    下一篇:【Spring JPA 更新查询-自定义删改】

  • 相关阅读:
    Elementary Methods in Number Theory Exercise 1.3.13
    Elementary Methods in Number Theory Exercise 1.3.17, 1.3.18, 1.3.19, 1.3.20, 1.3.21
    数论概论(Joseph H.Silverman) 习题 5.3,Elementary methods in number theory exercise 1.3.23
    Elementary Methods in Number Theory Exercise 1.2.31
    数论概论(Joseph H.Silverman) 习题 5.3,Elementary methods in number theory exercise 1.3.23
    Elementary Methods in Number Theory Exercise 1.3.13
    Elementary Methods in Number Theory Exercise 1.3.17, 1.3.18, 1.3.19, 1.3.20, 1.3.21
    Elementary Methods in Number Theory Exercise 1.2.31
    Elementary Methods in Number Theory Exercise 1.2.26 The Heisenberg group
    4__面向对象的PHP之作用域
  • 原文地址:https://www.cnblogs.com/masterchd/p/jpa.html
Copyright © 2020-2023  润新知