最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Spring Boot JPA Repository之existsBy查詢方法失效的解決

 更新時(shí)間:2021年06月10日 11:41:21   作者:bladestone  
這篇文章主要介紹了Spring Boot JPA Repository之existsBy查詢方法失效的解決方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教

引言: Spring Boot號(hào)稱微服務(wù)的利器,在結(jié)合了Spring Data與JPA之后,更是如虎添翼,開發(fā)快速的不像話,本文將講述一個(gè)關(guān)于JPA中一個(gè)詭異問題的診斷分析過程以及修復(fù)方法。

環(huán)境介紹

JDK 1.8 Spring 4.2 Spring Boot 1.5.9

問題描述

在Spring Data中的Repository接口中創(chuàng)建了一個(gè)檢查數(shù)據(jù)是否存在的接口方法:

@Repository
public interface VideoEntityRepository extends JpaRepository<VideoEntity, Long> {
    ........
    public boolean existsByUserIdAndName(long userId, String name);
   }

VideoEntity的類如下:

@SuppressWarnings("serial")
@Table(name="flook_video")
@Entity
@Data
@EqualsAndHashCode(callSuper=true)
public class VideoEntity extends BaseEntity {
    @Column(name="user_id")
    private long userId;
    @Column(name="name")
    private String name;
    @Column(name="change_version")
    private double changeVersion;
}

在調(diào)用方法existsBy方法的時(shí)候,返回的結(jié)果一直為false, 結(jié)果不正確,在偶的期望中,其執(zhí)行結(jié)果應(yīng)該不會(huì)出錯(cuò)的?那問題出在哪里呢?

關(guān)于existsBy的介紹

Spring Data提供了若干非常實(shí)用的擴(kuò)展,將數(shù)據(jù)庫(kù)表日常的CRUD操作都進(jìn)行很好的實(shí)現(xiàn),并提供了若干擴(kuò)展機(jī)制,基于一套簡(jiǎn)單易用的命名規(guī)則,來基于聲明式實(shí)現(xiàn)場(chǎng)景的數(shù)據(jù)庫(kù)查詢操作:

countByColumName
existsByColumnName

上述兩種方式都是由Spring Data來幫助動(dòng)態(tài)生成SQL的。

基于@Query方式

除了基于countBy/existsBy兩種方式之外,可以直接使用@Query方式來標(biāo)注特定的SQL或者JPQL來實(shí)現(xiàn)功能,由于這種方式需要些SQL,功能上完全覆蓋,但是工作量略大,不是最優(yōu)的方式。

問題分析

由于底層使用了Hibernate/JPA/Spring Data來實(shí)現(xiàn)的數(shù)據(jù)訪問層的實(shí)現(xiàn),所以,最好的方式當(dāng)然是查看動(dòng)態(tài)生成的SQL了,于是找到了生成的SQL語(yǔ)句:

select videoentit0_.id as col_0_0_ from video videoentit0_ where videoentit0_.user_id=? and videoentit0_.name=? limit ?

表的名稱是video,這個(gè)名稱是不對(duì)的。這個(gè)情況是怎么發(fā)生的呢?

問題的解決

經(jīng)過分析發(fā)現(xiàn),是由于在代碼中存在兩個(gè)類名完全相同VideoEntity的類,雖然在Repository中我們的的確確沒有引用錯(cuò)誤相關(guān)的,問題應(yīng)該出在當(dāng)Spring Data碰到兩個(gè)相同的類名之時(shí),其實(shí)不知道如何來生成SQL的,換句話說,其應(yīng)該是基于類名而非類路徑來動(dòng)態(tài)生成執(zhí)行SQL的。

TODO: 基于源代碼中找到相關(guān)部分內(nèi)容。

問題解決

將當(dāng)前的VideoEntity重新命名,確保不存在重名的問題,即使類的路徑不一樣,但是類名一樣,也是會(huì)產(chǎn)生這樣的問題。

從一個(gè)側(cè)面來分析,在Spring Data中所有的DataBean都是需要使用全路徑的類名的,否則同樣會(huì)出現(xiàn)問題。

JpaRepository 查詢規(guī)范

1.JpaRepository支持接口規(guī)范方法名查詢

意思是如果在接口中定義的查詢方法符合它的命名規(guī)則,就可以不用寫實(shí)現(xiàn),目前支持的關(guān)鍵字如下。

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相關(guān)查詢功能

a.Spring DataJPA框架在進(jìn)行方法名解析時(shí),會(huì)先把方法名多余的前綴截取掉,比如find、findBy、read、readBy、get、getBy,然后對(duì)剩下部分進(jìn)行解析。

b.假如創(chuàng)建如下的查詢:findByUserDepUuid(),框架在解析該方法時(shí),首先剔除findBy,然后對(duì)剩下的屬性進(jìn)行解析,假設(shè)查詢實(shí)體為Doc。

1:先判斷userDepUuid (根據(jù)POJO規(guī)范,首字母變?yōu)樾懀┦欠駷椴樵儗?shí)體的一個(gè)屬性,如果是,則表示根據(jù)該屬性進(jìn)行查詢;如果沒有該屬性,繼續(xù)第二步;

2:從右往左截取第一個(gè)大寫字母開頭的字符串此處為Uuid),然后檢查剩下的字符串是否為查詢實(shí)體的一個(gè)屬性,如果是,則表示根據(jù)該屬性進(jìn)行查詢;如果沒有該屬性,則重復(fù)第二步,繼續(xù)從右往左截?。蛔詈蠹僭O(shè)user為查詢實(shí)體的一個(gè)屬性;

3:接著處理剩下部分(DepUuid),先判斷user所對(duì)應(yīng)的類型是否有depUuid屬性,如果有,則表示該方法最終是根據(jù)“Doc.user.depUuid” 的取值進(jìn)行查詢;否則繼續(xù)按照步驟2的規(guī)則從右往左截取,最終表示根據(jù)“Doc.user.dep.uuid” 的值進(jìn)行查詢。

4:可能會(huì)存在一種特殊情況,比如Doc包含一個(gè)user的屬性,也有一個(gè)userDep 屬性,此時(shí)會(huì)存在混淆??梢悦鞔_在屬性之間加上"_"以顯式表達(dá)意圖,比如"findByUser_DepUuid()"或者"findByUserDep_uuid()"

c.特殊的參數(shù): 還可以直接在方法的參數(shù)上加入分頁(yè)或排序的參數(shù),比如:

Page<UserModel>findByName(String name, Pageable pageable);
List<UserModel>findByName(String name, Sort sort);

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

1:在實(shí)體類上使用@NamedQuery:

@NamedQuery(name ="UserModel.findByAge",query = "select o from UserModel
o where o.age >=?1")

2:在自己實(shí)現(xiàn)的DAO的Repository接口里面定義一個(gè)同名的方法,示例如下:

publicList<UserModel> findByAge(int age);

3:然后就可以使用了,Spring會(huì)先找是否有同名的NamedQuery,如果有,那么就不會(huì)按照接口定義的方法來解析。

e.還可以使用@Query來指定本地查詢,只要設(shè)置nativeQuery為true,比如:

@Query(value="select* from tbl_user where name like %?1" ,nativeQuery=true)
publicList<UserModel> findByUuidOrAge(String name);

注意:當(dāng)前版本的本地查詢不支持翻頁(yè)和動(dòng)態(tài)的排序

f.使用命名化參數(shù),使用@Param即可,比如:

@Query(value="selecto from UserModel o where o.name like %:nn")
publicList<UserModel> findByUuidOrAge(@Param("nn") String name);

g.同樣支持更新類的Query語(yǔ)句,添加@Modifying即可,比如:

@Modifying
@Query(value="updateUserModel o set o.name=:newName where o.name like %:nn")
public intfindByUuidOrAge(@Param("nn") String name,@Param("newName")String
newName);

注意:

1:方法的返回值應(yīng)該是int,表示更新語(yǔ)句所影響的行數(shù)

2:在調(diào)用的地方必須加事務(wù),沒有事務(wù)不能正常執(zhí)行

f.創(chuàng)建查詢的順序

Spring Data JPA在為接口創(chuàng)建代理對(duì)象時(shí),如果發(fā)現(xiàn)同時(shí)存在多種上述情況可用,它該優(yōu)先采用哪種策略呢?

<jpa:repositories>提供了query-lookup-strategy 屬性,用以指定查找的順序。

它有如下三個(gè)取值:

1:create-if-not-found:如果方法通過@Query指定了查詢語(yǔ)句,則使用該語(yǔ)句實(shí)現(xiàn)查詢;如果沒有,則查找是否定義了符合條件的命名查詢,如果找到,則使用該命名查詢;如果兩者都沒有找到,則通過解析方法名字來創(chuàng)建查詢。這是querylookup-strategy 屬性的默認(rèn)值

2:create:通過解析方法名字來創(chuàng)建查詢。即使有符合的命名查詢,或者方法通過

@Query指定的查詢語(yǔ)句,都將會(huì)被忽略

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

以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • java webApp異步上傳圖片實(shí)現(xiàn)代碼

    java webApp異步上傳圖片實(shí)現(xiàn)代碼

    這篇文章主要為大家詳細(xì)介紹了java webApp異步上傳圖片實(shí)現(xiàn)代碼,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-11-11
  • Java實(shí)現(xiàn)俄羅斯方塊的源碼分享

    Java實(shí)現(xiàn)俄羅斯方塊的源碼分享

    俄羅斯方塊是一個(gè)最初由阿列克謝帕吉特諾夫在蘇聯(lián)設(shè)計(jì)和編程的益智類視頻游戲。本文將利用Java語(yǔ)言實(shí)現(xiàn)這一經(jīng)典的小游戲,感興趣的可以學(xué)習(xí)一下
    2022-05-05
  • 詳細(xì)解讀java同步之synchronized解析

    詳細(xì)解讀java同步之synchronized解析

    synchronized關(guān)鍵字是Java里面最基本的同步手段,下面我們來一起學(xué)習(xí)一下
    2019-05-05
  • Java中淺拷貝和深拷貝詳解

    Java中淺拷貝和深拷貝詳解

    大家好,本篇文章主要講的是Java中淺拷貝和深拷貝詳解,感興趣的同學(xué)趕快來看一看吧,對(duì)你有幫助的話記得收藏一下,方便下次瀏覽
    2021-12-12
  • Java調(diào)用IK分詞器進(jìn)行分詞方式,封裝工具類

    Java調(diào)用IK分詞器進(jìn)行分詞方式,封裝工具類

    這篇文章主要介紹了Java調(diào)用IK分詞器進(jìn)行分詞方式,封裝工具類,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Java 操作Properties配置文件詳解

    Java 操作Properties配置文件詳解

    這篇文章主要介紹了Java 操作Properties配置文件詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • 如何使用JWT的SpringSecurity實(shí)現(xiàn)前后端分離

    如何使用JWT的SpringSecurity實(shí)現(xiàn)前后端分離

    這篇文章主要介紹了使用JWT的SpringSecurity實(shí)現(xiàn)前后端分離,登錄成功需要返回json數(shù)據(jù)登錄失敗需要返回json數(shù)據(jù)權(quán)限不足時(shí)返回json數(shù)據(jù)未登錄訪問資源返回json數(shù)據(jù),需要的朋友可以參考下
    2024-08-08
  • JVM Metaspace內(nèi)存溢出問題解決方案

    JVM Metaspace內(nèi)存溢出問題解決方案

    這篇文章主要介紹了JVM Metaspace內(nèi)存溢出排查總結(jié)過程圖解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-11-11
  • springboot開啟聲明式事務(wù)的方法

    springboot開啟聲明式事務(wù)的方法

    本篇文章主要介紹了springboot開啟聲明式事務(wù)的方法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-05-05
  • Maven導(dǎo)入Junit4后在test中無(wú)法引用問題

    Maven導(dǎo)入Junit4后在test中無(wú)法引用問題

    在使用Maven進(jìn)行項(xiàng)目管理時(shí),可能會(huì)遇到導(dǎo)入依賴和打開項(xiàng)目結(jié)構(gòu)的問題,本文通過實(shí)際經(jīng)驗(yàn),提供了一些解決方法和技巧,希望能幫助遇到相同問題的開發(fā)者,此外,還鼓勵(lì)大家多多支持和分享個(gè)人經(jīng)驗(yàn),以便于共同進(jìn)步
    2024-10-10

最新評(píng)論

体育| 夹江县| 延川县| 商水县| 曲靖市| 桂阳县| 博野县| 手游| 饶河县| 年辖:市辖区| 烟台市| 上高县| 东兰县| 丹巴县| 泽普县| 宕昌县| 扎兰屯市| 阿拉善盟| 长子县| 闵行区| 中西区| 固安县| 怀仁县| 蓝田县| 合川市| 塔河县| 赤水市| 宜阳县| 康定县| 望江县| 阳信县| 汉源县| 化州市| 巴彦淖尔市| 商丘市| 卢龙县| 安阳县| 治多县| 深州市| 河南省| 宜良县|