SpringDataJPA是Spring Data的一個子項目,經過提供基於JPA的Repository極大的減小了JPA做爲數據訪問方案的代碼量,你僅僅須要編寫一個接口集成下SpringDataJPA內部定義的接口便可完成簡單的CRUD操做,理論的東西不作多解釋,下面咱們開始講解SpringBootgit
咱們使用IntelliJ IDEA工具構建一個SpringBoot項目,預先導入Web、MySQL、JPA依賴,咱們簡單使用一個RestController來實現JPA的配置,以前也有講解JPA的簡單使用,今天詳細的講解下具體的細節性的內容,項目結構以下圖1所示:spring
咱們使用以前章節的配置,加入Druid數據源配置到咱們的項目中,複製第四章:使用Druid做爲SpringBoot項目數據源(添加監控)項目中的application.yml配置文件到咱們項目resources下,而且修改pom.xml添加Druid數據源依賴,以下圖2所示:sql
application.yml配置文件內容以下圖3所示(具體代碼請到碼雲下載地址:git.oschina.net/jnyqy/lesso…):數據庫
咱們在配置使用JpaRepository以前須要對應咱們的測試表添加實體映射,爲了本章的方便咱們直接使用第四章:使用Druid做爲SpringBoot項目數據源(添加監控)內的表結構以及實體,sql文件在第四章項目源碼的resource目錄下,能夠下載後自行加載到本地數據庫中,表結構以下圖4所示:tomcat
根據表結構建立對應的實體映射,簡單點,咱們使用單表操做,SpringDataJPA與Hibernate的語法一致內部都是使用了JPA的實現。映射實體代碼以下圖5所示:架構
上述圖5的getter/setter方法我沒有貼出來,自行工具構建就能夠了。咱們的準備作好了,下面咱們建立UserJPA接口,上圖5我已經建立到了jpa目錄內,建立完成後打開添加繼承自JpaRepository,JpaRepository須要泛型接口參數,第一個參數是實體,第二則是主鍵的類型,UserJPA代碼以下圖6所示:app
數據訪問的接口就算是實現了,咱們繼承的JpaRepository接口內有又繼承了PagingAndSortingRepository接口以及QueryByExampleExecutor接口,這兩個接口是用來幹什麼的?而PagingAndSortingRepository接口內部又有一個繼承自CrudRepository接口。若是對架構有點了解的朋友應該都知道,這樣設計得好處。框架
該接口內包含了最簡單的CRUD也就是Create、Read、Update、Delete方法,固然還有count、exists方法,以下圖7所示:less
若是自行定義的JPA繼承了該接口就會擁有CrudRepository接口內的全部方法實現。spring-boot
該接口繼承自CrudRepository接口,包含了最基本的CRUD方法的實現,該接口內部添加了兩個方法,以下圖8所示:
顧名思義,看到接口名稱就能夠聯想了,這個方法就是爲了分頁而設計的,固然不只僅是分頁還有排序方法。
咱們的JpaRepository接口繼承了該接口,這個接口提供條件查詢,複雜查詢方法,能夠經過Example方式進行查詢數據,源碼以下圖9所示:
後面咱們會講到QueryDSL,到那時你就會知道SpringDataJPA提供的複雜條件查詢並非最好的選擇。
咱們自定義的接口繼承了它,也就是說咱們的UserJPA擁有了JpaRepository接口及父類接口的全部方法實現,因此咱們並不須要添加任何數據操做代碼就能夠完成數據操做,JpaRepository接口對條件查詢以及保存集合數據添加了對應的方法,代碼以下圖10所示:
具體每一個方法是用來作什麼的,根據名稱就能夠看到,這裏就不作一一的講解了。下面咱們須要測試咱們建立的UserJPA是否能夠完成咱們上述說的數據操做。
咱們直接在controller包下建立一個UserController控制器,添加@RestController註解支持,咱們由於方便這裏就不編寫Service層的代碼實現了,直接在Controller內注入UserJPA,代碼以下圖11所示:
咱們在UserController內添加了JpaRepository內部實現的findAll方法,用來查詢所有用戶數據,下面咱們啓動項目測試。
當你使用SpringBootApplication方式運行項目時控制檯會輸出項目運行失敗的日誌提示,這裏咱們須要註釋掉spring-boot-starter-tomcat依賴的scope屬性就能夠了。
嘗試訪問用戶列表地址:127.0.0.1:8080/list,能夠看到頁面輸出了一條數據,這條數據是我事先在數據庫中手動添加的,以下圖12所示:
咱們編寫簡單的添加數據方法在UserController內,代碼以下圖13所示:
咱們在add方法內建立了一個UserEntity對象並對全部的字段都賦值。
注意:SpringDataJPA內有個save方法,這個方法不只僅是用來添加數據使用,當咱們傳入主鍵的值時則是根據主鍵的值完成更新數據操做。
咱們重啓下項目,嘗試訪問127.0.0.1:8080/add地址,界面輸出內容以下圖14所示:
界面給了咱們數據添加成功的提示,咱們訪問list地址驗證是否已經添加成功,以下圖15所示:
能夠看到,數據已經經過add方法添加到數據庫內。因爲更新的操做與添加一致這裏就不作講解了,你只須要傳入主鍵的值便可。
咱們簡單實現刪除一條數據,在UserController內添加delete方法,方法接受一個主鍵參數,以下圖16所示:
當咱們訪問/delete時傳入userId參數就能夠刪除對應的數據,下面咱們重啓下項目,訪問127.0.0.1:8080/delete?userId=5,界面輸入內容以下圖17所示:
數據已經成功的完成了刪除操做。
上面的操做一切都是SpringDataJPA爲咱們自動完成的,到目前爲止咱們並無編寫一句SQL,那麼SpringDataJPA是否支持自定義SQL語句呢?答案必須是確定的!由於它是這個的強大!
SpringDataJPA內部有兩種方式能夠實現自定義SQL功能,咱們先來說述使用註解的方式,後期在SpringDataJPA核心技術專題內再詳細的講解使用EntityManager是如何完成自定義SQL、調用存儲過程、視圖等等操做的。下面咱們打開UserJPA接口,添加自定義查詢年齡大於20的數據,以下圖18所示:
@Query是用來配置自定義SQL的註解,後面參數nativeQuery = true纔是代表了使用原生的sql,若是不配置,默認是false,則使用HQL查詢方式。咱們在UserController內添加方法/age,測試咱們的自定義SQL是否有效,代碼以下圖19所示:
重啓下項目,訪問127.0.0.1:8080/age,效果以下圖20所示:
從名字上能夠看到咱們的@Query註解好像只是用來查詢的,可是若是配合@Modifying註解一共使用,則能夠完成數據的刪除、添加、更新操做。下面咱們來測試下自定義SQL完成刪除數據的操做,我根據名字、密碼字段共同刪除一個數據,接口代碼以下圖21所示:
咱們再來編寫UserController添加對應的方法調用deleteQuery接口方法,以下圖22所示:
重啓下項目,訪問地址:127.0.0.1:8080/deleteWhere,界面輸出內容以下圖23所示:
界面居然出現了異常,這是怎麼回事呢?能夠看到拋出的異常TranscationRequiredException,意思就是你當前的操做給你拋出了須要事務異常,SpringDataJPA自定義SQL時須要在對應的接口或者調用接口的地方添加事務註解@Transactional,來開啓事務自動化管理。下面咱們在UserJPA內添加@Transactional註解,重啓項目再來訪問剛纔的地址,效果以下圖24所示:
界面已經給我提示了刪除成功,咱們查看下控制檯看打印的SQL是不是咱們自定義的,以下圖25所示:
咱們自定義的SQL被成功的打印了,自定義SQL完成添加,更新操做時跟刪除一致,都須要添加@Query以及@Modifying註解配合使用。
項目在正常狀況下不只僅只繼承一個JpaRepository接口,下一章咱們整合SpringDataJPA跟QueryDSL時就須要添加多個接口繼承了,那麼咱們業務數據接口每個都去繼承幾個相同的接口?答案確定是 NO,固然多個繼承也是能夠的,不過對於系統設計還有代碼複用性來講並非最好的選擇!
咱們建立一個包名叫作base,在包內添加一個BaseRepository接口,而且接口繼承咱們的JpaRepository,代碼以下圖26所示:
又出現了一個新的註解,@NoRepositoryBean,這個註解是用來幹什麼的呢?
Spring開源程序猿在命名規則上應該是比較嚴格的,從名字上咱們幾乎就能夠判斷出用途,這個註解若是配置在繼承了JpaRepository接口以及其餘SpringDataJpa內部的接口的子接口時,子接口不被做爲一個Repository建立代理實現類。
咱們建立的業務數據接口直接繼承BaseRepository就好了,繼承的子接口會擁有JpaRepository全部方法實現。
分頁對於大型系統來講確定是必不可少的,那麼咱們在SpringDataJpa內是如何使用分頁來完成查詢的呢?
通常狀況咱們會建立一個BaseEntity,在BaseEntity內添加幾個字段:排序列,排序方式,當前頁碼,每頁條數等,下面咱們也來建立這麼一個父類,代碼以下圖27所示:
咱們修改UserEntity繼承BaseEntity,而後在數據庫內添加上幾條測試數據,咱們每次頁面的數量就不用20了,咱們在建立查詢條件時修改爲2條。
咱們打開UserController添加cutPage方法,用於做爲分頁查詢入口,(注意:文章的講解都沒有添加Service層因此全部的業務邏輯都在Controller內處理的,正式項目請不要這樣編寫。)咱們在cutPage方法內添加對應的分頁邏輯,以下圖28所示:
接下來咱們重啓下項目,訪問地址:127.0.0.1:8080/cutpage?page=1,查看界面輸出效果以下圖29所示:
咱們再來看下控制檯的輸出,以下圖30所示:
能夠看到控制檯給咱們打印了兩條SQL,第一條是分頁查詢的SQL,第二條是查詢表內總數量的SQL。SpringDataJPA內部對數量作出了封裝,你能夠經過Page對象也就是PagingAndSortingRepository接口內的findAll(PageRequest request)方法的返回值類型中獲取到總條數、總頁數。
咱們上面在BaseEntity內添加了排序的字段以及排序方式,咱們從新編輯下cutPage方法,修改pageRequest建立方式,添加Sort對象到PageRequest對象內,就能夠實現排序數據。以下圖31所示:
上圖31能夠看到咱們修改了排序字段咱們使用了默認的id,(注意:這裏的排序字段不是數據庫內的字段名而是實體內的屬性名)以及排序方式改爲了倒序,SpringDataJPA對排序方式添加了一個枚舉類型,建立Sort對象時也須要枚舉對象,由於咱們BaseEntity配置的是字符串因此上面多了一步判斷排序方式返回枚舉對象。
重啓下項目,再來訪問分頁路徑,界面輸出效果以下圖32所示:
能夠看到數據已是倒序方式展現了,控制檯的日誌輸出也對應的添加了order by語句,以下圖33所示:
綜上所述本章的內容已經講解完了,本章的內容比較多昨天完成沒有編寫完,還請見諒。本章主要講解了SpringBoot項目中使用SpringDataJPA的基本操做,包括了:CURD、分頁、排序、自定義SQL、定義BaseRepository、事務處理等。本章內容並非SpringDataJPA全面內容,後續我會在SpringDataJPA核心技術專題詳細講解。
本章內容已經更新到碼雲:
SpringBoot配套源碼地址:gitee.com/hengboy/spr…
SpringCloud配套源碼地址:gitee.com/hengboy/spr…
SpringBoot相關係列文章請訪問:目錄:SpringBoot學習目錄
QueryDSL相關係列文章請訪問:QueryDSL通用查詢框架學習目錄
SpringDataJPA相關係列文章請訪問:目錄:SpringDataJPA學習目錄
SpringBoot相關文章請訪問:目錄:SpringBoot學習目錄,感謝閱讀!
歡迎加入QQ技術交流羣,共同進步。