1. 程式人生 > >【SpringBoot學習筆記】SpringBoot_01_SpringData—JpaRepository查詢功能

【SpringBoot學習筆記】SpringBoot_01_SpringData—JpaRepository查詢功能

1.JpaRepository支援介面規範方法名查詢

如果在介面中定義的查詢方法符合它的命名規則,就可以不用寫實現類


2.相關功能查詢

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);

注意:
方法的返回值應該是int,表示更新語句所影響的行數
在呼叫的地方必須加事務,沒有事務不能正常執行

h.建立查詢的順序

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

1)create-if-not-found:如果方法通過@Query指定了查詢語句,則使用該語句實現
查詢;如果沒有,則查詢是否定義了符合條件的命名查詢,如果找到,則使用該
命名查詢;如果兩者都沒有找到,則通過解析方法名字來建立查詢。這是querylookup-
strategy 屬性的預設值

2)create:通過解析方法名字來建立查詢。即使有符合的命名查詢,或者方法通過
@Query指定的查詢語句,都將會被忽略

3)use-declared-query:如果方法通過@Query指定了查詢語句,則使用該語句實現
查詢;如果沒有,則查詢是否定義了符合條件的命名查詢,如果找到,則使用該
命名查詢;如果兩者都沒有找到,則丟擲異常