SpringDataJpa——JpaRepository查詢功能

1.JpaRepository支持接口規範方法名查詢。意思是如果在接口中定義的查詢方法符合它的命名規則,就可以不用寫實現,目前支持的關鍵字如下。

Keyword Sample JPQL snippet
IsNotNull findByAgeNotNull ...  where x.age not null
Like findByNameLike ...  where x.name like ?1
NotLike findByNameNotLike ...  where x.name not like ?1
StartingWith findByNameStartingWith ...  where x.name like ?1(parameter bound with appended %)
EndingWith findByNameEndingWith ...  where x.name like ?1(parameter bound with prepended %)
Containing findByNameContaining ...  where x.name like ?1(parameter bound wrapped in %)
OrderBy findByAgeOrderByName ...  where x.age = ?1 order by x.name desc
Not findByNameNot ...  where x.name <> ?1
In findByAgeIn ...  where x.age in ?1
NotIn findByAgeNotIn ...  where x.age not in ?1
True findByActiveTrue ...  where x.avtive = true
Flase findByActiveFalse ...  where x.active = false
And  findByNameAndAge ...  where x.name = ?1 and x.age = ?2
Or findByNameOrAge ...  where x.name = ?1 or x.age = ?2
Between findBtAgeBetween ...  where x.age between ?1 and ?2
LessThan findByAgeLessThan ...  where x.age  <  ?1
GreaterThan findByAgeGreaterThan ...  where x.age > ?1
After/Before ... ...
IsNull findByAgeIsNull ...  where x.age is null

2.JpaRepository相關查詢功能

a.Spring Data JPA框架在進行方法名解析時,會先把方法名多餘的前綴截取掉,比如find、findBy、read、readBy、get、getBy,然後對剩下部分進行解析。

b.假如創建如下的查詢:findByUserDepUuid(),框架在解析該方法時,首先剔除
findBy,然後對剩下的屬性進行解析,假設查詢實體爲Doc。

1:先判斷userDepUuid (根據POJO 規範,首字母變爲小寫)是否爲查詢實體的一個

屬性,如果是,則表示根據該屬性進行查詢;如果沒有該屬性,繼續第二步;

2:從右往左截取第一個大寫字母開頭的字符串此處爲Uuid),然後檢查剩下的字符串是

否爲查詢實體的一個屬性,如果是,則表示根據該屬性進行查詢;如果沒有該屬性,

則重複第二步,繼續從右往左截取;最後假設user爲查詢實體的一個屬性;

3:接着處理剩下部分(DepUuid),先判斷user 所對應的類型是否有depUuid屬性,如

果有,則表示該方法最終是根據“ Doc.user.depUuid” 的取值進行查詢;否則繼

續按照步驟2 的規則從右往左截取,最終表示根據“Doc.user.dep.uuid” 的值進

行查詢。

4:可能會存在一種特殊情況,比如Doc包含一個user 的屬性,也有一個userDep 屬

性,此時會存在混淆。可以明確在屬性之間加上"_" 以顯式表達意圖,比如

"findByUser_DepUuid()" 或者"findByUserDep_uuid()"

c.特殊的參數: 還可以直接在方法的參數上加入分頁或排序的參數,比如:
Page<UserModel> findByName(String name, Pageable pageable);
List<UserModel> findByName(String name, Sort sort);

d.也可以使用JPA的NamedQueries,方法如下:

1:在實體類上使用@NamedQuery,示例如下:
@NamedQuery(name = "UserModel.findByAge",query = "select o from UserModel
o where o.age >= ?1")
2:在自己實現的DAO的Repository接口裏面定義一個同名的方法,示例如下:
public List<UserModel> findByAge(int age);
3:然後就可以使用了,Spring會先找是否有同名的NamedQuery,如果有,那麼就不
會按照接口定義的方法來解析。

e.還可以使用@Query來指定本地查詢,只要設置nativeQuery爲true,比如:
@Query(value="select * from tbl_user where name like %?1" ,nativeQuery=true)
public List<UserModel> findByUuidOrAge(String name);

注意:當前版本的本地查詢不支持翻頁和動態的排序

f.使用命名化參數,使用@Param即可,比如:
@Query(value="select o from UserModel o where o.name like %:nn")
public List<UserModel> findByUuidOrAge(@Param("nn") String name);

g.同樣支持更新類的Query語句,添加@Modifying即可,比如:
@Modifying
@Query(value="update UserModel o set o.name=:newName where o.name like %:nn")
public int findByUuidOrAge(@Param("nn") String name,@Param("newName") String
newName);
注意:
1:方法的返回值應該是int,表示更新語句所影響的行數
2:在調用的地方必須加事務,沒有事務不能正常執行

f.創建查詢的順序
Spring Data JPA 在爲接口創建代理對象時,如果發現同時存在多種上述
情況可用,它該優先採用哪種策略呢?
<jpa:repositories> 提供了query-lookup-strategy 屬性,用以指定查
找的順序。它有如下三個取值:

1:create-if-not-found:如果方法通過@Query指定了查詢語句,則使用該語句實現
查詢;如果沒有,則查找是否定義了符合條件的命名查詢,如果找到,則使用該
命名查詢;如果兩者都沒有找到,則通過解析方法名字來創建查詢。這是querylookup-
strategy 屬性的默認值
2:create:通過解析方法名字來創建查詢。即使有符合的命名查詢,或者方法通過
@Query指定的查詢語句,都將會被忽略
3:use-declared-query:如果方法通過@Query指定了查詢語句,則使用該語句實現
查詢;如果沒有,則查找是否定義了符合條件的命名查詢,如果找到,則使用該
命名查詢;如果兩者都沒有找到,則拋出異常


發佈了63 篇原創文章 · 獲贊 12 · 訪問量 10萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章