javascript
01 | Spring Data JPA 初识
課程正式開始了,這里我會以一個案例的形式來和你講解如何通過 Spring Boot 結合 Spring Data JPA 快速啟動一個項目、如何使用 UserRepository 完成對 User 表的操作、如何寫測試用例等幾個知識點,同時帶你體驗一下 Spring Data JPA 的優勢。通過這個課時,希望你能夠對 JPA 建立一個整體的認識。
提示:在本課程中如果沒有特殊說明,JPA 就是指 Spring Data JPA。
話不多說,我們先來看一個案例。
Spring Boot 和 Spring Data JPA 的 Demo演示
我們利用 JPA + Spring Boot 簡單做一個 RESTful API 接口,方便你來了解 Spring Data JPA 是干什么用的,具體步驟如下。
第一步:利用 IDEA 和 SpringBoot 2.3.3 快速創建一個案例項目。
點擊“菜單” | New Project 命令,選擇 Spring Initializr 選項,如下圖所示。
這里我們利用 Spring 官方的 Start 來創建一個項目,接下來選擇 Spring Boot 的依賴:
-
Lombok:幫我們創建一個簡單的 Entity 的 POJO,主要用來省去創建 GET 和 SET 方法;
-
Spring Web:MVC 必備組件;
-
Spring Data JPA:重頭戲,這是本課時的重點內容;
-
H2 Database:內存數據庫;
-
Spring Boot Actuator:監控我們項目狀態使用。
然后通過下圖操作界面選擇上面提到的這些依賴,如下圖所示:
第二步:通過 IDEA 的圖形化界面,一路單擊 Next 按鈕,然后單擊 Finsh 按鈕,得到一個工程,完成后結構如下圖所示:
現在我們已經可以創建一個 Spring Boot + JPA 的項目了,那么接下來我們看看怎么對 User 表進行增刪改查操作。
第三步:新增 3 個類來完成對 User 的 CURD。
第一個類:新增 User.java,它是一個實體類,用來做 User 表的映射的,如下所示:
第二個類:新增 UserRepository,它是我們的 DAO 層,用來操作實體 User 進行增刪改成操作,如下所示:
package com.example.jpa.example1;import org.springframework.data.jpa.repository.JpaRepository;public interface UserRepository extends JpaRepository<User,Long> {}第三個類:新增 UserController,它是 Controller,用來創建 Rest 的 API 的接口的,如下所示:
package com.example.jpa.example1;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.data.domain.Page;import org.springframework.data.domain.Pageable;import org.springframework.http.MediaType;import org.springframework.web.bind.annotation.*;@RestController@RequestMapping(path = "/api/v1")public class UserController {@Autowiredprivate UserRepository userRepository;/*** 保存用戶* @param user* @return*/@PostMapping(path = "user",consumes = {MediaType.APPLICATION_JSON_VALUE})public User addNewUser(@RequestBody User user) {return userRepository.save(user);}/*** 根據分頁信息查詢用戶* @param request* @return*/@GetMapping(path = "users")@ResponseBodypublic Page<User> getAllUsers(Pageable request) {return userRepository.findAll(request);}}最終,我們的項目結構變成如下圖所示的模樣:
上圖中,appliaction.properties 里面的內容是空的,到現在三步搞定,其他什么都不需要配置,直接點擊 JpaApplication 這個類,就可啟動我們的項目了。
第四步:調用項目里面的 User 相關的 API 接口測試一下。
我們再新增一個 JpaApplication.http 文件,內容如下:
POST /api/v1/user HTTP/1.1Host: 127.0.0.1:8080Content-Type: application/jsonCache-Control: no-cache{"name":"jack","email":"123@126.com"}#######GET http://127.0.0.1:8080/api/v1/users?size=3&page=0###點擊“運行”按鈕,效果如下圖所示:
運行結果如下:
關于 IDEA 運行 Grandle 項目的小技巧: 在實際工作中,我們啟動運行或者是跑測試用例的時候,經常以 Gradle 的方式運行,或者用 Application 的方式運行,兩種方式進行隨意切換,需要設置的地方如下圖所示:
通過以上案例,我們知道了 Spring Data JPA 可以幫我們做數據的 CRUD 操作,掌握到了JPA + Spring Boot 如何啟動和集成 JPA,以及對如何創建一個數據庫操作也有了一定的了解。那么接下來,我們看下是如何切換默認數據源的,如切換成 MySQL。
JPA 如何整合 MySQL 數據庫?
關于 JPA 與 MySQL 的集成我們分為兩部分來展開:如何切換 MySQL 數據源、如何寫測試用例進行測試。
1. 切換 MySQL 數據源
上面的例子,我們采用的是默認 H2 數據源的方式,這個時候你肯定會問:“H2 重啟,數據丟失了怎么辦?”那么我們調整一下上面的代碼,以 MySQL 作為數據源,看看需要改動哪些。
第一處改動,application.properties 內容如下:
spring.datasource.url=jdbc:mysql://localhost:3306/testspring.datasource.username=rootspring.datasource.password=rootspring.jpa.generate-ddl=true第二處改動,刪除 H2 數據源,新增 MySQL 數據庫驅動:
調整完畢之后,我們重啟這個項目,以同樣的方式測試上面的兩個接口依然 OK。
其實這個時候可以發現一件事情,那就是我沒有手動去創建任何表,而 JPA 自動幫我創建了數據庫的 DDL,并新增了 User 表,所以當我們用 JPA 之后創建表的工作就不會那么復雜了,我們只需要把實體寫好就可以了。
以上是切換 MySQL 數據源需要進行的操作,接下來看看測試用例怎么寫,在修改代碼的時候我們就不需要頻繁重啟項目了,當你掌握 JUnit 之后,可以提升開發效率。
2. Spring Data JPA 測試用例的寫法
我們這里只關注 Repository 的測試用例的寫法,Controller 和 Service 等更復雜的測試我們在測試課時再詳細介紹,這里我們先快速體驗一下。
第一步,在 Test 目錄里增加 UserRepositoryTest 類:
package com.example.jpa.example1;import org.junit.Assert;import org.junit.jupiter.api.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest;import java.util.List;@DataJpaTestpublic class UserRepositoryTest {@Autowiredprivate UserRepository userRepository;@Testpublic void testSaveUser() {User user = userRepository.save(User.builder().name("jackxx").email("123456@126.com").build());Assert.assertNotNull(user);List<User> users= userRepository.findAll();System.out.println(users);Assert.assertNotNull(users);}}第二步,我們可直接運行測試用例,進行真實的 DB 操作,通過控制臺來看下我們的測試用例是否能夠跑通,如下圖所示:
通過上圖可以看到,測試的時候執行的 SQL 有哪些,那么我們到底是連接的 MySQL 做的測試用例,還是連接的 H2 做的測試呢?在后面的第 30 課時(單元測試和集成測試)的時候我會為你詳細揭曉,到時你會發現測試用例寫起來也是如此簡單。
整體認識 JPA
通過上面的兩個例子我們已經快速入門了,知道了 Spring Boot 結合 Spring Data JPA 怎么配置和啟動一個項目 ,之后當你熟悉了 JPA 之后,你還會發現 Spring Boot JPA 要比我們配置 MyBatis 簡單很多。下面我們來整體認識一下 Java Persistence API 究竟是什么。
介紹 JPA 協議之前,我們先來對比了解下市面上的 ORM 框架有哪些,分別有哪些優缺點,做到心里有數。
1. 市場上 ORM 框架比對
下表是市場上比較流行的 ORM 框架,這里我羅列了 MyBatis、Hibernate、Spring Data JPA 等,并對比了下它們的優缺點。
經過對比,你可以看到我們正在學習的 Spring Data JPA 還是比較前衛的,很受歡迎,繼承了 Hibernate 的很多優點,上手又比較簡單。所以,我非常建議你好好學習一下。
2. Java Persistence API 介紹和開源實現
JPA 是 JDK 5.0 新增的協議,通過相關持久層注解(@Entity 里面的各種注解)來描述對象和關系型數據里面的表映射關系,并將 Java 項目運行期的實體對象,通過一種Session持久化到數據庫中。
想象一下,一旦協議有了,大家都遵守了此種協議進行開發,那么周邊開源產品就會大量出現,比如我們在后面要介紹的第 29 課時(Spring Data Rest 是什么?和 JPA 是什么關系?)就可以基于這套標準,進而對 Entity 的操作再進行封裝,從而可以得到更加全面的 Rest 協議的 API接口。
再比如 JSON API(https://jsonapi.org/)協議,就是雅虎的大牛基于 JPA 的協議的基礎,封裝制定的一套 RESTful 風格、JSON 格式的 API 協議,那么一旦 JSON API 協議成了標準,就會有很多周邊開源產品出現。比如很多 JSON API 的客戶端、現在比較流行的 Ember 前端框架,就是基于 Entity 這套 JPA 服務端的協議,在前端解析 API 協議,從而可以對普通 JSON 和 JSON API 的操作進行再封裝。
所以規范是一件很有意思的事情,突然之間世界大變樣,很多東西都一樣了,我們的思路就需要轉換了。
JPA 的內容分類
-
一套 API 標準定義了一套接口,在 javax.persistence 的包下面,用來操作實體對象,執行 CRUD 操作,而實現的框架(Hibernate)替代我們完成所有的事情,讓開發者從煩瑣的 JDBC 和 SQL 代碼中解脫出來,更加聚焦自己的業務代碼,并且使架構師架構出來的代碼更加可控。
-
定義了一套基于對象的 SQL:Java Persistence Query Language(JPQL),像 Hibernate 一樣,我們通過寫面向對象(JPQL)而非面向數據庫的查詢語言(SQL)查詢數據,避免了程序與數據庫 SQL 語句耦合嚴重,比較適合跨數據源的場景(一會兒 MySQL,一會兒 Oracle 等)。
-
ORM(Object/Relational Metadata)對象注解映射關系,JPA 直接通過注解的方式來表示 Java 的實體對象及元數據對象和數據表之間的映射關系,框架將實體對象與 Session 進行關聯,通過操作 Session 中不通實體的狀態,從而實現數據庫的操作,并實現持久化到數據庫表中的操作,與 DB 實現同步。
詳細的協議內容你感興趣的話也可以看一下官方的文檔。
JPA 的開源實現
JPA 的宗旨是為 POJO 提供持久化標準規范,可以集成在 Spring 的全家桶使用,也可以直接寫獨立 application 使用,任何用到 DB 操作的場景,都可以使用,極大地方便開發和測試,所以 JPA 的理念已經深入人心了。Spring Data JPA、Hibernate 3.2+、TopLink 10.1.3 以及 OpenJPA、QueryDSL 都是實現 JPA 協議的框架,他們之間的關系結構如下圖所示:
俗話說得好:“未來已經來臨,只是尚未流行”,大神資深開發用 Spring Data JPA,編程極客者用 JPA;而普通 Java 開發者,不想去挑戰的 Java“搬磚者”用 Mybatis。
到這里,相信你已經對 JPA 有了一定的認識,接下來我們了解一下 Spring Data,看看它都有哪些子項目。
2. Spring Data 的子項目有哪些
下圖為目前 Spring Data 的框架分類結構圖,里面都有哪些模塊可以一目了然,也可以知道哪些是我們需要關心的項目。
主要項目(Main Modules):
Spring Data Commons,相當于定義了一套抽象的接口,下一課時我們會具體介紹
Spring Data Gemfire
Spring Data JPA,我們關注的重點,對 Spring Data Common 的接口的 JPA 協議的實現
Spring Data KeyValue
Spring Data LDAP
Spring Data MongoDB
Spring Data REST
Spring Data Redis
Spring Data for Apache Cassandra
Spring Data for Apache Solr
社區支持的項目(Community Modules):
Spring Data Aerospike
Spring Data Couchbase
Spring Data DynamoDB
Spring Data Elasticsearch
Spring Data Hazelcast
Spring Data Jest
Spring Data Neo4j
Spring Data Vault
其他(Related Modules):
Spring Data JDBC Extensions
Spring for Apache Hadoop
Spring Content
關于 Spring Data 的子項目,除了上面這些,還有很多開源社區版本,比如 Spring Data、MyBatis 等,這里就不一一介紹了,感興趣的同學可以到 Spring 社區,或者 GitHub 上進行查閱。
總結
本課時的主要目的是帶領你快速入門,從 H2 數據源和 Mysql 數據源兩個方面為你介紹了 Spring Data JPA 數據操作的概念,了解了 Repository 的寫法,快速體驗一把 Spring Data JPA 的便捷之處。
希望你通過本節課的學習可以對 Spring Data JPA + Spring Boot 有一個整體的認識,為以后的技術進階打下良好的基礎。在掌握了基本知識以后,你會發現 Spring Data JPA 是 ORM 的效率利器,后面課程我會一一揭開 Spring Data JPA 的神秘面紗,帶你掌握其實現原理和實戰經驗,讓你在實際開發中游刃有余。
對于本課時所講的知識點,歡迎你在下方留言區表達自己的學習感悟,大家一起討論,共同進步。
補充一個TIPS:課程中的案例是依賴 lombok 插件的,如下圖所示:
并開啟 annotation processing。
點擊下方鏈接查看源碼(不定時更新)
spring-data-jpa
總結
以上是生活随笔為你收集整理的01 | Spring Data JPA 初识的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Spring Boot2.0 JPA 实
- 下一篇: 02 | Spring Data Com