Spring Data JPA入門-JPQL和命名查詢

JPQL和命名查詢

在使用Spring Data JPA的過程中,框架通過解析方法名稱的方式生成對應(yīng)的SQL,確實為我們減少了很多的工作量,但是,也特殊情況,需要我們手寫SQL,當(dāng)然,這里是JPQL(一種面向?qū)ο蟮腟QL語法結(jié)構(gòu))

使用@Query注解創(chuàng)建查詢,將該注解貼在dao的方法上,然后提供一個需要的JPQL語句即可,如:

@Query("SELECT p FROM Person p WHERE name LIKE %?1%")
Person findByName(String name);

如果不使用Query注解,那么Spring Data JPA為我們生成的SQL應(yīng)該是:

Hibernate: select person0_.id as id1_0_, person0_.age as age2_0_, person0_.name as name3_0_ 
            from Person person0_ where person0_.name=?

使用注解之后執(zhí)行的SQL:

Hibernate: select person0_.id as id1_0_, person0_.age as age2_0_, person0_.name as name3_0_ 
            from Person person0_ where person0_.name like ?

所以,我們可以通過這種方式來自定義需要執(zhí)行的SQL語句,這樣可以讓我們開發(fā)者更加自如的來完成我們的需求

很多開發(fā)者在創(chuàng)建 JPQL 時喜歡使用命名參數(shù)來代替位置編號,@Query 也對此提供了支持。JPQL 語句中通過”: 變量”的格式來指定參數(shù)乳丰,同時在方法的參數(shù)前面使用 @Param 將方法參數(shù)與 JPQL中的命名參數(shù)對應(yīng)口锭,示例如下:

@Query("SELECT p FROM Person p WHERE name LIKE %:name%")
Person findByName(@Param("name") String name);

此時大家應(yīng)該會想一個問題,上面我們都在說如何執(zhí)行查詢操作,查詢的SQL可以自動生成也可自定義,那么增刪改操作的SQL可以嗎?也可以自定生成響應(yīng)的SQL嗎?

答案是肯定的,這里,我們需要使用@Modifying注解來標識該方法執(zhí)行的是更新或者刪除操作,如:

@Modifying
@Query("UPDATE Person p SET p.name = :name WHERE p.id = :id")
void updatePersonName(@Param("id") Integer id, @Param("name") String name);

如此這般,框架執(zhí)行的就不是查詢的SQL,而是更新的SQL

通過調(diào)用 JPA 命名查詢語句創(chuàng)建查詢

命名查詢是 JPA 提供的一種將查詢語句從方法體中獨立出來类嗤,以供多個方法共用的功能祈餐。Spring Data JPA 對命名查詢也提供了很好的支持瀑踢。用戶只需要按照 JPA 規(guī)范在 orm.xml 文件或者在實體類中使用 @NamedQuery(或 @NamedNativeQuery)定義好查詢語句扳还,唯一要做的就是為該語句命名時,需要滿足”DomainClass.methodName”的命名規(guī)則丘损。假設(shè)定義了如下接口:

Person findByName(@Param("name") String name);

同時在實體類中定義JPQL或者SQL

@NamedQuery(name = "Person.findByName", query = "SELECT p FROM Person p WHERE p.name LIKE :name")
public class Person {
}

此時name屬性的值需要按照規(guī)則定義,Spring Data JPA根據(jù)name屬性的值找到對應(yīng)的JPQL語句并執(zhí)行

Spring Data JPA的查詢策略

以上,我們說到了三種執(zhí)行SQL的方式,

  1. 框架通過解析方法名稱,生成對應(yīng)的SQL語句
  2. 使用@Query聲明JPQL,這樣就可以執(zhí)行我們自定義的語句
  3. Spring Data JPA所支持的命名查詢

這里我們來看看框架是如何選擇使用哪一種的執(zhí)行查詢的方式:

Spring Data JPA 在為接口創(chuàng)建代理對象時普办,如果發(fā)現(xiàn)同時存在多種上述情況可用,它該優(yōu)先采用哪種策略呢徘钥?為此衔蹲,<jpa:repositories> 提供了 query-lookup-strategy 屬性,用以指定查找的順序呈础。它有如下三個取值:

  1. create —- 通過解析方法名字來創(chuàng)建查詢舆驶。即使有符合的命名查詢,或者方法通過 @Query 指定的查詢語句而钞,都將會被忽略沙廉。

  2. create-if-not-found —- 如果方法通過 @Query 指定了查詢語句,則使用該語句實現(xiàn)查詢臼节;如果沒有撬陵,則查找是否定義了符合條件的命名查詢珊皿,如果找到,則使用該命名查詢巨税;如果兩者都沒有找到蟋定,則通過解析方法名字來創(chuàng)建查詢。這是 query-lookup-strategy 屬性的默認值草添。

  3. use-declared-query —- 如果方法通過 @Query 指定了查詢語句驶兜,則使用該語句實現(xiàn)查詢;如果沒有远寸,則查找是否定義了符合條件的命名查詢抄淑,如果找到,則使用該命名查詢驰后;如果兩者都沒有找到肆资,則拋出異常。

為接口中的部分方法提供自定義實現(xiàn)
在實際開發(fā)中,我們會遇到一些需要自定義持久層實現(xiàn)的需求,也就是Spring Data JPA的實現(xiàn)不能滿足我們的要求,所以Spring Data JPA考慮到了這一點,為我們提供了自定義實現(xiàn)持久層的方式

將需要開發(fā)者手動實現(xiàn)的方法從持久層接口(假設(shè)為 UserDao )中抽取出來灶芝,獨立成一個新的接口(假設(shè)為 IUserDaoBase )迅耘,并讓 IUserDao 繼承 IUserDaoBase;
為 IUserDaoBase 提供自定義實現(xiàn)(假設(shè)為 IUserDaoBaseImpl )监署;
將 IUserDaoBaseImpl 配置為 Spring Bean;
在 <jpa:repositories> 中按下面的方式進行配置纽哥。

<jpa:repositories base-package="cn.wolfcode.spring_jdbc_jpa.dao"> 
<jpa:repository id="userDao" repository-impl-ref=" userDaoBase " /></jpa:repositories> 

<bean id="userDaoBase" class="......."/>

此外钠乏,<jpa:repositories > 提供了一個 repository-impl-postfix 屬性,用以指定實現(xiàn)類的后綴春塌。如:

<jpa:repositories base-package="cn.wolfcode.spring_jdbc_jpa.dao"
repository-impl-postfix="Impl"/>

在框架掃描到 IUserDao 接口時晓避,它將嘗試在相同的包目錄下查找 IUserDaoImpl.java,如果找到只壳,便將其中的實現(xiàn)方法作為最終生成的代理類中相應(yīng)方法的實現(xiàn)俏拱。

到此,Spring Data JPA的基本使用我們就先到這

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市吼句,隨后出現(xiàn)的幾起案子锅必,更是在濱河造成了極大的恐慌,老刑警劉巖惕艳,帶你破解...
    沈念sama閱讀 221,273評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件搞隐,死亡現(xiàn)場離奇詭異,居然都是意外死亡远搪,警方通過查閱死者的電腦和手機劣纲,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,349評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來谁鳍,“玉大人癞季,你說我怎么就攤上這事劫瞳。” “怎么了绷柒?”我有些...
    開封第一講書人閱讀 167,709評論 0 360
  • 文/不壞的土叔 我叫張陵志于,是天一觀的道長。 經(jīng)常有香客問我辉巡,道長恨憎,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,520評論 1 296
  • 正文 為了忘掉前任郊楣,我火速辦了婚禮憔恳,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘净蚤。我一直安慰自己钥组,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 68,515評論 6 397
  • 文/花漫 我一把揭開白布今瀑。 她就那樣靜靜地躺著程梦,像睡著了一般。 火紅的嫁衣襯著肌膚如雪橘荠。 梳的紋絲不亂的頭發(fā)上屿附,一...
    開封第一講書人閱讀 52,158評論 1 308
  • 那天,我揣著相機與錄音哥童,去河邊找鬼挺份。 笑死,一個胖子當(dāng)著我的面吹牛贮懈,可吹牛的內(nèi)容都是我干的匀泊。 我是一名探鬼主播,決...
    沈念sama閱讀 40,755評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼朵你,長吁一口氣:“原來是場噩夢啊……” “哼各聘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起抡医,我...
    開封第一講書人閱讀 39,660評論 0 276
  • 序言:老撾萬榮一對情侶失蹤躲因,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后魂拦,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體毛仪,經(jīng)...
    沈念sama閱讀 46,203評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,287評論 3 340
  • 正文 我和宋清朗相戀三年芯勘,在試婚紗的時候發(fā)現(xiàn)自己被綠了箱靴。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,427評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡荷愕,死狀恐怖衡怀,靈堂內(nèi)的尸體忽然破棺而出棍矛,到底是詐尸還是另有隱情,我是刑警寧澤抛杨,帶...
    沈念sama閱讀 36,122評論 5 349
  • 正文 年R本政府宣布够委,位于F島的核電站,受9級特大地震影響怖现,放射性物質(zhì)發(fā)生泄漏茁帽。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,801評論 3 333
  • 文/蒙蒙 一屈嗤、第九天 我趴在偏房一處隱蔽的房頂上張望潘拨。 院中可真熱鬧,春花似錦饶号、人聲如沸铁追。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,272評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽琅束。三九已至,卻和暖如春算谈,著一層夾襖步出監(jiān)牢的瞬間涩禀,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,393評論 1 272
  • 我被黑心中介騙來泰國打工然眼, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留埋泵,地道東北人。 一個月前我還...
    沈念sama閱讀 48,808評論 3 376
  • 正文 我出身青樓罪治,卻偏偏與公主長得像,于是被迫代替她去往敵國和親礁蔗。 傳聞我的和親對象是個殘疾皇子觉义,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,440評論 2 359

推薦閱讀更多精彩內(nèi)容