日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区

您的位置:首頁技術文章
文章詳情頁

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

瀏覽:115日期:2023-03-05 16:38:37

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

環境介紹

JDK 1.8 Spring 4.2 Spring Boot 1.5.9

問題描述

在Spring Data中的Repository接口中創建了一個檢查數據是否存在的接口方法:

@Repositorypublic 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;}

在調用方法existsBy方法的時候,返回的結果一直為false, 結果不正確,在偶的期望中,其執行結果應該不會出錯的?那問題出在哪里呢?

關于existsBy的介紹

Spring Data提供了若干非常實用的擴展,將數據庫表日常的CRUD操作都進行很好的實現,并提供了若干擴展機制,基于一套簡單易用的命名規則,來基于聲明式實現場景的數據庫查詢操作:

countByColumNameexistsByColumnName

上述兩種方式都是由Spring Data來幫助動態生成SQL的。

基于@Query方式

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

問題分析

由于底層使用了Hibernate/JPA/Spring Data來實現的數據訪問層的實現,所以,最好的方式當然是查看動態生成的SQL了,于是找到了生成的SQL語句:

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

表的名稱是video,這個名稱是不對的。這個情況是怎么發生的呢?

問題的解決

經過分析發現,是由于在代碼中存在兩個類名完全相同VideoEntity的類,雖然在Repository中我們的的確確沒有引用錯誤相關的,問題應該出在當Spring Data碰到兩個相同的類名之時,其實不知道如何來生成SQL的,換句話說,其應該是基于類名而非類路徑來動態生成執行SQL的。

TODO: 基于源代碼中找到相關部分內容。

問題解決

將當前的VideoEntity重新命名,確保不存在重名的問題,即使類的路徑不一樣,但是類名一樣,也是會產生這樣的問題。

從一個側面來分析,在Spring Data中所有的DataBean都是需要使用全路徑的類名的,否則同樣會出現問題。

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 DataJPA框架在進行方法名解析時,會先把方法名多余的前綴截取掉,比如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 UserModelo where o.age >=?1')

2:在自己實現的DAO的Repository接口里面定義一個同名的方法,示例如下:

publicList<UserModel> findByAge(int age);

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

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

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

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

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

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

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

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

注意:

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指定了查詢語句,則使用該語句實現查詢;如果沒有,則查找是否定義了符合條件的命名查詢,如果找到,則使用該命名查詢;如果兩者都沒有找到,則拋出異常

以上為個人經驗,希望能給大家一個參考,也希望大家多多支持好吧啦網。

標簽: Spring
相關文章:
日本不卡不码高清免费观看,久久国产精品久久w女人spa,黄色aa久久,三上悠亚国产精品一区二区三区
国产精品久久久久av电视剧| 蜜桃久久久久久| 蜜桃av一区二区| 欧美午夜不卡| 中文久久精品| 老司机久久99久久精品播放免费| 国产精品社区| 久久不射网站| 伊人久久大香线蕉av不卡| 亚洲成人二区| 亚洲激情久久| 久久高清免费观看| 免费日本视频一区| 麻豆精品网站| 日韩精品三区四区| 久久精品凹凸全集| 国产一区二区三区四区五区| 人在线成免费视频| 伊人久久成人| 亚洲丝袜美腿一区| 69精品国产久热在线观看| 欧美日韩一区二区三区不卡视频 | 亚洲综合二区| 亚洲视频电影在线| 久久国产乱子精品免费女| 国产精品成人国产| 精品一区二区三区四区五区| 高潮一区二区| 91精品精品| 99视频精品免费观看| 日韩欧美三区| 国产精品mm| 久久久一本精品| 免费观看在线综合色| 国产精品中文| 久久久久国产| 亚洲男人在线| 久久久精品国产**网站| 久久久久久久久久久妇女| 男人的天堂亚洲一区| 亚洲资源网站| 国产精品videosex极品| 精品欧美一区二区三区在线观看| 五月天久久网站| 视频一区欧美日韩| 久久婷婷国产| 欧美成人高清| 91福利精品在线观看| 日韩成人三级| 日韩激情av在线| 亚洲天堂av影院| 日本不卡一二三区黄网| av在线最新| 日韩精品欧美成人高清一区二区| 日韩综合一区| 亚洲精选久久| 97精品视频在线看| 亚洲欧洲美洲国产香蕉| 久久毛片亚洲| 免费在线观看一区二区三区| 精品亚洲精品| 免费在线成人网| 四虎国产精品免费观看| 亚洲伊人影院| 四虎4545www国产精品 | 欧美网站在线| 成人午夜毛片| 另类国产ts人妖高潮视频| 麻豆精品在线播放| 久热精品在线| 久久国产小视频| 免费观看亚洲天堂| 亚洲一区av| 欧美亚洲在线日韩| 麻豆传媒一区二区三区| 奶水喷射视频一区| 免费污视频在线一区| 国产欧美大片| 亚洲深深色噜噜狠狠爱网站| 丝袜av一区| 精品中文在线| 欧美日韩亚洲一区| 伊人久久大香线蕉av不卡| 精品一二三区| 国产亚洲久久| 蜜桃视频第一区免费观看| 日韩美女一区二区三区在线观看| 91成人精品在线| 视频一区在线播放| 欧美手机在线| 毛片在线网站| 精品视频高潮| 国产乱码精品| 亚洲精品亚洲人成在线观看| 国产精品av一区二区| 国产videos久久| 国产精品v一区二区三区| 免费在线视频一区| 视频一区国产视频| 亚洲免费婷婷| 亚洲精品极品少妇16p| 欧美日韩免费观看视频| 精品美女在线视频| 国产精品一区二区美女视频免费看 | 成人午夜网址| 久久wwww| 国产美女视频一区二区| 亚洲免费成人av在线| 午夜宅男久久久| 欧美亚洲精品在线| 麻豆精品蜜桃| 蜜桃精品在线| 日本美女一区| 日产精品一区二区| 激情综合婷婷| 电影91久久久| 欧美激情国产在线| 精品国产99| 日本一二区不卡| 在线看片国产福利你懂的| 另类专区亚洲| 亚洲成av人片一区二区密柚 | 国产成人久久精品麻豆二区| 国产精品一区二区美女视频免费看| 日本伊人久久| 日韩精品亚洲专区| 国产三级一区| 国产精品porn| 国产精品99一区二区三| 91欧美日韩| 99久久99久久精品国产片果冰| 久久人人88| 亚洲中字黄色| 亚洲乱码久久| 国产视频网站一区二区三区| 免费视频一区二区三区在线观看| 美女久久99| 天堂а√在线最新版中文在线| 国产自产自拍视频在线观看| 美女网站视频一区| 欧美日韩精品免费观看视频完整| 亚洲一区二区三区免费在线观看| 综合干狼人综合首页| 四虎精品一区二区免费| 91嫩草精品| 精品欠久久久中文字幕加勒比| 激情视频网站在线播放色| 久久精品在线| 日韩中文字幕av电影| 日韩av中文字幕一区二区| 国产激情综合| 日本精品不卡| 视频一区中文字幕国产| 在线精品一区二区| 国产乱码精品一区二区三区四区 | 国产欧美69| 国产传媒在线| 亚洲精品极品少妇16p| 亚洲青青久久| 久久精品国产一区二区| 亚洲午夜精品久久久久久app| 日韩一区欧美二区| 国产精品中文字幕亚洲欧美| 9999国产精品| 国产视频一区欧美| 国产女人18毛片水真多18精品| 亚洲欧洲美洲av| 久久天堂精品| 日本一区二区三区视频在线看| 国产精品va| 久久天堂av| 日韩高清欧美激情| 国产第一亚洲| 男女男精品网站| 国模精品一区| 热久久国产精品| 福利精品在线| 免费人成在线不卡| 精品72久久久久中文字幕| 在线国产一区| 久久wwww| 巨乳诱惑日韩免费av| 日韩高清成人在线| 日本精品影院| 国产精品日本| 欧美日本一区| 欧美1区2区3| 99久久夜色精品国产亚洲狼 | 亚洲人成在线网站| 亚州精品视频| 日韩精品午夜| 欧美日韩一区二区三区四区在线观看 | 老鸭窝亚洲一区二区三区| 欧美国产先锋| 免费欧美日韩| 青青青免费在线视频| 日本视频一区二区| 国产一区视频在线观看免费| 国产精品中文字幕制服诱惑| 日韩亚洲一区在线|