JPA學習總結


一. 背景相關
JDK:1.8
IDE:IntelliJ IDEA
db:MYSQL
Spring Boot 結合 JPA
Spring Boot版本:v2.0.2.RELEASE
使用maven管理jar包


二:POMhtml

 1   <dependencies>
 2         <dependency>
 3             <groupId>org.springframework.boot</groupId>
 4             <artifactId>spring-boot-starter-test</artifactId>
 5             <scope>test</scope>
 6         </dependency>
 7         <!--JPA-->
 8         <dependency>
 9             <groupId>org.springframework.boot</groupId>
10             <artifactId>spring-boot-starter-data-jpa</artifactId>
11         </dependency>
12         <!--熱部署-->
13         <dependency>
14             <groupId>org.springframework.boot</groupId>
15             <artifactId>spring-boot-devtools</artifactId>
16             <scope>runtime</scope>
17             <optional>true</optional>
18         </dependency>
19         <!--MySql數據庫-->
20         <dependency>
21             <groupId>mysql</groupId>
22             <artifactId>mysql-connector-java</artifactId>
23             <scope>runtime</scope>
24         </dependency>
25         <!--Pageable使用QPageRequest須要這個-->
26         <dependency>
27             <groupId>com.querydsl</groupId>
28             <artifactId>querydsl-jpa</artifactId>
29         </dependency>
30     </dependencies>
31 
32     <build>
33         <plugins>
34             <plugin>
35                 <groupId>org.springframework.boot</groupId>
36                 <artifactId>spring-boot-maven-plugin</artifactId>
37                 <configuration>
38                     <fork>true</fork>
39                 </configuration>
40             </plugin>
41         </plugins>
42     </build>

 



三:材料準備
兩張實體表 teacher、studnett
java

 1 @Entity
 2 @Table(name = "student")
 3 public class Student {
 4 
 5 @Id
 6 @GeneratedValue
 7 private Long id;
 8 @Column(name = "stu_name")
 9 private String stuName;
10 
11 ....


注意: get、set方法自行完善

四. 主要總結內容
(1)Repository
(2)CrudRepository
(3)PagingAndSortingRepository
(4)JpaRepository
(5)JpaSpecificationExecutor

1. repository繼承圖示
mysql

 

繼承關係是:
JpaRepository 繼承PagingAndSortingRepository,PagingAndSortingRepository繼承CrudRepository,CrudRepository繼承Repository

能夠看出:
(1)都是接口
(2)上面的的繼承關係中並無JpaSpecificationExecutor,這個是獨立的

2. Repository接口
  先點進去,看看,是一個空接口,也就是一個標記接口
spring

  繼承這個接口能幹什麼?查詢
  知足其必定的命名規範去書寫方法名,能夠不用本身寫sql語句,直接執行查詢sql


  示例:
數據庫

 

  測試:
數組

 

  結果:
maven

 

  解釋:咱們能夠在Repository裏自定義方法,可是命名規範是定死的,不是大風颳來的,好比說,方法名的開頭通常以 find | get | read 爲開頭spring-boot

  看圖:
測試

 

  具體的命名規範,建議看官方文檔https://docs.spring.io/spring-data/jpa/docs/2.0.7.RELEASE/reference/html/

  總結:
    自定義一個接口,繼承Repository接口,知足必定命名規範書寫方法名,就能夠不用手寫sql語句,執行查詢操做

3.@Query註解
  上面已經說了,繼承Repository接口,便可實現查詢,那麼增刪改查呢中的增刪改呢?
  好的,使用@Query註解,能夠實現增、刪、改。

  準備:

     A. 此時,須要書寫JPQL語句,而且須要用到三個註解@Query、@Modifying、@Transactional
     B. 方法分爲有參和無參

  (1)以更新操做爲例子
     1)這裏先以無參方法爲例,實現一個修改的操做

 

  通常在service層開啓註解

 

  開始測試:

 

  結果:


  2)帶參方法,實現一個修改的操做
    傳參方式有兩種:命名參數、佔位符
    先來第一種:
      英文的冒號   ‘ :’ ,後面加上自定義的名字,冒號和名字之間無空格
      這裏還漏了一點,使用命名參數傳參,須要在參數中使用@Param註解,裏面的值要和JPQL裏定義參數名的同樣

  A. 使用命名參數示例:

 

 

  service層記住開啓註解

 

  測試:

 

  結果:

 

  注意:

    其實還有一點,這一點能夠和接下來的佔位符進行比較,
    當有參方法有兩個及以上參數時,好比下面這個,參數的傳遞順序隨意,由於有@Param限定好了


  B. 使用佔位符示例:

 

  英文的  '?' ,後面跟着的1啊、2啊或者3456等等,組合起來就表示第一個佔位符,第二個佔位符...
  注意:由於使用佔位符,參數傳遞順序嚴格按照JPQL語句中的順序,不能亂,這與使用命名參數傳參的不一樣


  因此,我建議使用命名參數傳參,省得錯亂!

  (3)若是不熟JPQL語句怎麼辦?用原生sql語句查詢
    將上面那個改造一下

  nativeQuery = true 即爲使用原生sql
  注意:由於是原生sql語句,全部記得表名和字段都要和數據庫字段屬性一一對應起來

  (4)爲何會有JPQL語句?爲何還支持原生sql語句?
    就用官方事先實現好的,以及知足JPA命名規範的自定義方法去查詢或者更新不行嗎?
    還真不行!
    好比說,我這有個子查詢,怎麼查?查不了吧。。。
    這裏用JPQL或者原生sql就很簡單


  (5)like模糊查詢
    這裏講講使用@Query的模糊查詢,主要是 '%'的用法,有兩種


    1)傳遞參數時,在參數兩邊用%

 

    2)直接寫在@Query裏


    推薦使用第二種,傳參就老老實實傳參,別瞎折騰

    總結:
      1> 記住  @Query、@Modifying、@Transactional、@Param 這四個註解的用處
      2> 使用JPQL語句能夠執行查詢、修改、刪除的操做,不能進行增長數據的操做
      3> 使用原生sql語句能夠實現增的操做,就是nativeQuery = true(上面忘記說了)
      4> 默認狀況下,spring Data 的每一個方法上都有事務,但都是隻讀事務(read-only),是沒法完成修改數據的操做行爲的,因此,如果涉及到對數據進行改動的操做,請開啓事務@Transactional
      5> 帶參方法傳參有兩種方式,命名參數、佔位符,我我的推薦命名參數
      6> like 模糊查詢傳參也有兩種方式,我的建議直接寫在JPQL語句內更好

4. CrudRepository接口
  先點進去,看看,能夠看出官方已經定義好了一些經常使用CRUD的方法

 

  方法都是見名知義啊,就很少作解釋了
  舉個例子吧:
  以前咱們已經寫好一個findAll的方法,如今我把他給註釋了

 

  而後就報錯了

 

  由於個人返回類型和官方的不同

  

  改改唄:

 

  這種時候,這些簡單CRUD方法,就不用本身寫了,也就是說,本身既能夠不用寫sql,也不用寫自定義方法,用官方提供的現成的就行

  總結:自定義一個接口,繼承CrudRepository接口,直接就能夠調用官方提供的一套現成的CRUD方法,美滋滋


5. PagingAndSortingRepository接口
  這個也是見名知義的 --分頁、排序用的
  點進去,看看

 

  好的,來實現一個分頁排序功能
  在這以前,我先把以前的表刪了,從新生成,再造點數據,都是官方提供的deleteAll、save方法


  如今數據庫中的數據長這樣

 

  (1)分頁
  我想把寫好的方法給你們看看,以後再解釋

 

  而後結果:

 

  每頁顯示5條記錄,第三頁,id從16開始,這不扯犢子嗎?id不該該從11開始嗎?
  這是第一個問題:page的索引是從0開始的,因此,改一下


  結果:

 

  第二個問題:這個id是從11開始了,可是這應該是第三頁啊。
  再改

 

 

  (2)分頁好了,還有排序

 


 

  總結:PagingAndSortingRepository接口主要就是用來實現分頁排序的

6. JpaRepository接口
  老規矩,點進去看看

 

  總結:這個嘛,沒什麼好說的,看方法名就能夠了

7. JpaSpecificationExecutor接口,最後一個

 


  問題:他是用來幹嗎的?
  解釋:仍是用來分頁,可是是用他來組合條件分頁

  回想一下上面實現的分頁功能,除了傳進去一個起始頁和一個每頁顯示記錄數以及排序條件,還傳了什麼?
  沒了,就這三個。夠用嗎,不夠啊。
  我想帶個參數模糊查詢不給啊?
  我想帶個id比較比較不給啊?

  OK!
  在上面實現分頁的基礎上,我增長兩個條件,一個是模糊查詢,一個是id比較
  先看,以後我再解釋

 

  結果:

 


  解釋一下:
    root: 表明查詢的實體類。(這裏即爲Student)
    criteriaQuery: 能夠從中可到Root對象,即告知JPA Criteria查詢要查詢哪個實體類, 還能夠來添加查詢條件,還能夠結合EntityManager對象獲得最終查詢的TypedQuery對象。
    CriteriaBuilder : 用於建立Criteria 相關對象的工廠。固然能夠從中獲取到Predicate對象
    Predicate 類型,表明一個查詢條件

  或者再將上面改改,畢竟參數都是傳遞過來的,不是大風颳來的


  其實這樣仍是有問題,思考一下,因爲業務的變動,需求變動,即要判斷的條件可能更多了
  這種時候,一開始就用一個數組存放條件不夠優雅,畢竟數組的大小是寫死的
  來來來,換成集合走一波


  總結:當你想用組合條件分頁查,繼承JpaRepository<T, ID>, JpaSpecificationExecutor<T>唄

  綜上,
    平常使用,自定義一個接口,繼承JpaRepository接口,
    又想組合條件分頁查,繼承JpaSpecificationExecutor接口

相關文章
相關標籤/搜索