javascript
Spring Data JPA 从入门到精通~@Query详解
語法及其源碼
public @interface Query {/*** 指定JPQL的查詢語句。(nativeQuery=true的時候,是原生的Sql語句)*/String value() default "";/*** 指定count的JPQL語句,如果不指定將根據query自動生成。* (如果當nativeQuery=true的時候,指的是原生的Sql語句)*/String countQuery() default "";/*** 根據哪個字段來count,一般默認即可。*/String countProjection() default "";/*** 默認是false,表示value里面是不是原生的sql語句*/boolean nativeQuery() default false;/*** 可以指定一個query的名字,必須唯一的。* 如果不指定,默認的生成規則是:* {$domainClass}.${queryMethodName}*/String name() default "";/** 可以指定一個count的query的名字,必須唯一的。* 如果不指定,默認的生成規則是:* {$domainClass}.${queryMethodName}.count*/String countName() default ""; }@Query 用法
使用命名查詢為實體聲明查詢是一種有效的方法,對于少量查詢很有效。一般只需要關心 @Query 里面的 value 和 nativeQuery 的值。使用聲明式 JPQL 查詢有個好處,就是啟動的時候就知道你的語法正確不正確。
| 注意:好的架構師寫代碼時報錯的順序是編譯<啟動<運行時,即越早發現錯誤越好。默認 value 里面是 JPQL 語法,既對象查詢和 SQL、HQL 比較類似。 |
案例 4.1:聲明一個注解在 Repository 的查詢方法上。
public interface UserRepository extends JpaRepository<User, Long>{@Query("select u from User u where u.emailAddress = ?1")User findByEmailAddress(String emailAddress); }案例 4.2:Like 查詢,注意 firstname 不會自動加上 % 關鍵字。
public interface UserRepository extends JpaRepository<User, Long> {@Query("select u from User u where u.firstname like %?1")List<User> findByFirstnameEndsWith(String firstname); }案例 4.3:直接用原始 SQL。
public interface UserRepository extends JpaRepository<User, Long> {@Query(value = "SELECT * FROM USERS WHERE EMAIL_ADDRESS = ?1", nativeQuery = true)User findByEmailAddress(String emailAddress); }注意:nativeQuery 不支持直接 Sort 的參數查詢。
案例4.4:nativeQuery 的排序錯誤的寫法,下面這個是啟動不起來的。
public interface UserRepository extends JpaRepository<User, Long> { @Query(value = "select * from user_info where first_name=?1",nativeQuery = true) List<UserInfoEntity> findByFirstName(String firstName,Sort sort); }案例4.5:nativeQuery 排序的寫法。
@Query(value = "select * from user_info where first_name=?1 order by ?2",nativeQuery = true) List<UserInfoEntity> findByFirstName(String firstName,String sort); //調用的地方寫法last_name是數據里面的字段名,不是對象的字段名 repository.findByFirstName("jackzhang","last_name");@Query 的排序
@Query 的 JPQL 情況下,想實現排序,方法上面直接用 PageRequest 或者直接用 Sort 參數都可以做到。
在排序實例中實際使用的屬性需要與實體模型里面的字段相匹配,這意味著它們需要解析為查詢中使用的屬性或別名。這是一個state_field_path_expression JPQL定義,并且 Sort 的對象支持一些特定的函數。
案例 4.6:Sort and JpaSort 的使用。
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)")); repo.findByAndSort("targaryen", JpaSort.unsafe("LENGTH(firstname)")); repo.findByAsArrayAndSort("bolton", new Sort("fn_len"));@Query 的分頁
案例 4.7:直接用 Page 對象接受接口,參數直接用 Pageable 的實現類即可。
public interface UserRepository extends JpaRepository<User, Long> {@Query(value = "select u from User u where u.lastname = ?1")Page<User> findByLastname(String lastname, Pageable pageable); } //調用者的寫法 repository.findByFirstName("jackzhang",new PageRequest(1,10));案例 4.8:對原生 SQL 的分頁支持,案例如下,但是支持的不是特別友好,以 MySQL 為例。
public interface UserRepository extends JpaRepository<UserInfoEntity, Integer>, JpaSpecificationExecutor<UserInfoEntity> {@Query(value = "select * from user_info where first_name=?1 /* #pageable# */",countQuery = "select count(*) from user_info where first_name=?1",nativeQuery = true)Page<UserInfoEntity> findByFirstName(String firstName, Pageable pageable); } //調用者的寫法 return userRepository.findByFirstName("jackzhang",new PageRequest(1,10, Sort.Direction.DESC,"last_name")); //打印出來的sql select * from user_info where first_name=? /* #pageable# */ order by last_name desc limit ?, ?注意:
- 這個注釋 /* #pageable# */ 必須有;
- 估計有可能隨著版本的變化這個會做優化。
- 另外一種實現方法就是自己寫兩個查詢方法,自己手動分頁。
總結
以上是生活随笔為你收集整理的Spring Data JPA 从入门到精通~@Query详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Separate Query from
- 下一篇: gradle idea java ssm