iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0
Software Development

spring boot 3 學習筆記系列 第 23

Day23 - Spring Data JPA 入門:從 H2 到 PostgreSQL

  • 分享至 

  • xImage
  •  

如果你想讓你的應用程式能夠儲存和讀取資料,那麼 Spring Data JPA 絕對是你需要認識的好夥伴。今天內容將用最簡單的方式,來了解什麼是 JPA,並學會如何設定開發和生產環境的資料庫。

什麼是 JPA?為什麼我們需要它?

在開始之前,我們先來初步了解 JPA (Java Persistence API)

想像一下,在 Java 程式中,我們操作的是「物件」(Object),例如一個 User 物件,它有 idnameemail 等屬性。但在資料庫中,我們儲存的是「資料列」(Row),例如 users 資料表中的一筆紀錄,它有 idnameemail 等欄位。這兩者結構不同,直接溝通起來很麻煩。

傳統上,我們需要手動編寫一堆稱為 JDBC 的程式碼,把物件的屬性一個個取出來,組合成 SQL 語法,再存入資料庫。反過來,也要手動把資料庫的欄位一個個讀出來,再放回物件裡。這個過程不僅程式碼冗長、重複,而且只要 SQL 語法有任何微小變動,就必須修改 Java 程式碼。當應用程式規模變大時,維護成本會變得非常高且容易出錯。

https://ithelp.ithome.com.tw/upload/images/20250910/20171829jXIlwmSRJo.png

ORM 與 JPA 的誕生

為了解決這個問題,ORM (Object-Relational Mapping, 物件關聯對映) 的概念應運而生。ORM 就像一個專業的自動翻譯機,它能自動幫我們把 Java 物件「對映」到資料庫的資料表,讓我們可以用操作物件的方式,間接操作資料庫。

// 使用 JPA 後,儲存一個使用者可能只需要這樣一行程式碼
userRepository.save(newUser);

JPA 正是 Java 官方為 ORM 制定的一套「標準規範」或「介面」。它只定義了規則(例如:你應該用 @Entity 標註一個物件,用 @Id 標註主鍵),但不提供具體的實現方法。

這就好比 JPA 是一份建築藍圖,它規定了房子要有門、有窗戶,但沒有說明要用什麼材料蓋。Hibernate 就是業界最知名的「建築公司」之一,它根據 JPA 這份藍圖,提供了完整且強大的實作。

使用 JPA 的好處:

  • 大幅簡化程式碼:告別繁瑣的 JDBC 和手寫 SQL,讓程式碼更乾淨、更易讀。
  • 資料庫獨立性(Database Agnostic):因為我們是針對 JPA 規範寫程式,所以未來要從 MySQL 換到 PostgreSQL,通常只需要更換 JDBC 驅動程式並修改設定檔,而不需要改動大量的業務邏輯程式碼。
  • 專注於業務邏輯:開發者可以將精力集中在應用程式的核心功能,而不是被繁瑣的資料庫操作細節所困擾。
  • 善用物件導向的優勢:可以利用繼承、多型等物件導向特性來設計資料模型。

Spring Data JPA 則是 Spring 家族的一員,它在 JPA 的基礎上又做了一層抽象和簡化。它提供了一系列強大的 Repository 介面,我們甚至不需要寫任何實作類別,就能自動獲得 CRUD(新增、讀取、更新、刪除)等常用功能,讓我們可以用更少量的程式碼來完成資料庫操作,來提升開發效率極致。

快速開始:使用 H2 資料庫(記憶體中資料庫)

有時候對於剛開始開發或進行單元測試的階段,我們不希望每次都得啟動一個完整的資料庫系統。這時候,H2 就是我們的最佳選擇。

什麼是 H2?

H2 是一個用 Java 編寫的輕量級「記憶體中資料庫」(In-Memory Database)。它的特點是:

  • 速度快:所有資料都儲存在 RAM 中,讀寫效能極高,非常適合自動化測試。
  • 免安裝與設定:它會以函式庫的形式內嵌在我們的應用程式中,跟著 Spring Boot 應用程式一起啟動和關閉。
  • 資料易失性:當應用程式關閉時,所有資料都會消失。這在開發和測試時非常方便,因為每次重啟都能確保我們在一個乾淨、可預期的環境下開始。

設定步驟

第一步:加入依賴 (Dependency)

在你的 pom.xml 檔案中,確認有加入 spring-boot-starter-data-jpah2 的依賴 (Dependency)。

<dependencies>
    <!-- Spring Data JPA 核心依賴,它會自動引入 JPA API 和 Hibernate 等相關套件 -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>

    <!-- H2 資料庫依賴 -->
    <dependency>
        <groupId>com.h2database</groupId>
        <artifactId>h2</artifactId>
        <!-- scope 設定為 runtime 表示這個依賴在編譯時期不需要,只在執行時期需要 -->
        <scope>runtime</scope>
    </dependency>
</dependencies>

第二步:設定 application.properties

src/main/resources/application.properties 檔案中加入以下設定。Spring Boot 會偵測到 H2 在 classpath 中,並自動進行大部分的設定,但我們可以覆寫這些設定以符合我們的需求。

# --- H2 資料庫設定 ---

# 啟用 H2 Console,這是一個內建的網頁管理介面,非常適合在開發時查看資料庫狀態
spring.h2.console.enabled=true
# 設定 H2 Console 的路徑,預設就是 /h2-console
spring.h2.console.path=/h2-console

# 資料庫連線 URL。'jdbc:h2:mem:testdb' 的意思是:
# jdbc:h2 -> 使用 H2 資料庫
# mem -> 資料庫模式為記憶體模式
# testdb -> 資料庫的名稱是 testdb
spring.datasource.url=jdbc:h2:mem:testdb

# 資料庫驅動程式的類別名稱,Spring Boot 通常會自動偵測,但明確寫出是個好習慣
spring.datasource.driverClassName=org.h2.Driver

# 登入資料庫的預設帳號和密碼
spring.datasource.username=sa
spring.datasource.password=

# 告訴 Hibernate 我們正在使用 H2 資料庫的 SQL 方言 (Dialect)
# 方言能讓 Hibernate 產生針對特定資料庫優化的 SQL 語法
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect

第三步:啟動並測試

現在啟動你的 Spring Boot 應用程式。啟動完成後,打開瀏覽器,前往 http://localhost:8080/h2-console

你會看到一個登入頁面。請務必確認 JDBC URL 欄位的值與你在 application.properties 中設定的 jdbc:h2:mem:testdb 完全一致。如果不同,請手動修改,然後點擊「Connect」。如果成功,你就可以看到資料庫的管理介面了,即使目前裡面還沒有任何資料表。

https://ithelp.ithome.com.tw/upload/images/20250910/20171829v8vBvtBvzY.png

https://ithelp.ithome.com.tw/upload/images/20250910/20171829REcaWm2lDA.png

實際應用:配置 PostgreSQL 資料庫

當你的應用程式準備要部署到測試或正式環境時,就需要一個能夠永久儲存資料的資料庫,例如:PostgreSQL。PostgreSQL 是一個功能強大、穩定且開源的關聯式資料庫,被廣泛應用於各種規模的專案中。

假設你已經在你的電腦或伺服器上安裝好了 PostgreSQL,並使用 psqlpgAdmin 等工具建立了一個空的資料庫。

設定步驟

第一步:加入依賴 (Dependency)

首先,我們需要 PostgreSQL 的 JDBC 驅動程式,它負責讓我們的 Java 應用程式能與 PostgreSQL 資料庫溝通。在 pom.xml 中加入以下依賴(你也可以同時保留 H2 的依賴,以便在不同環境切換使用)。

<dependency>
    <groupId>org.postgresql</groupId>
    <artifactId>postgresql</artifactId>
    <version>42.7.7</version>
    <scope>runtime</scope>
</dependency>

第二步:修改 application.properties

現在,我們將資料庫連線設定從 H2 改成 PostgreSQL。你可以先把 H2 的設定註解 (Comment) 掉(在每一行前面加上 #),或是使用 Spring Profiles 來管理不同環境的設定(這是更進階也更推薦的做法)。

# --- PostgreSQL 資料庫設定 ---

# 你的 PostgreSQL 資料庫連線 URL
# 格式: jdbc:postgresql://<主機名稱或IP>:<埠號>/<資料庫名稱>
# localhost:5432 是 PostgreSQL 的預設主機和埠號
spring.datasource.url=jdbc:postgresql://localhost:5432/mydatabase

# 你的 PostgreSQL 登入帳號和密碼,請務必換成你自己的設定
spring.datasource.username=myuser
spring.datasource.password=mypassword

# 告訴 Hibernate 我們正在使用 PostgreSQL 的 SQL 方言
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect

# 這是 JPA 中一個非常重要的設定,它決定了 Hibernate 如何處理資料表的結構
# 'update' 在開發初期很方便,但生產環境建議使用 'validate' 或 'none'
spring.jpa.hibernate.ddl-auto=update

現在重啟你的應用程式。如果設定無誤,它就會成功連線到你的 PostgreSQL 資料庫。如果你的應用程式中有定義 Entity,且 ddl-auto 設定為 updatecreate,你將會在 PostgreSQL 資料庫中看到自動建立的資料表。

深入了解:重要的資料庫連線設定

application.properties 中,有幾個關鍵設定值得我們深入了解,它們對應用程式的行為有著重大的影響。

  • spring.datasource.url

    • 資料庫連線位址。每個資料庫的格式都不同,例如:
      • MySQL: jdbc:mysql://localhost:3306/mydatabase?useSSL=false&serverTimezone=UTC
      • PostgreSQL: jdbc:postgresql://localhost:5432/mydatabase
      • SQL Server: jdbc:sqlserver://localhost:1433;databaseName=mydatabase
  • spring.datasource.username / spring.datasource.password

    • 登入資料庫的帳號密碼。在正式環境中,強烈建議使用環境變數或配置中心(如 Spring Cloud Config)來管理這些敏感資訊,而不是直接寫在程式碼中。
  • spring.jpa.hibernate.ddl-auto

    • 這個設定告訴 Hibernate 如何處理資料庫的 Schema(也就是資料表的結構)。理解它們的區別至關重要:
說明 適用場景 風險
none 什麼都不做。完全關閉 DDL (Data Definition Language) 自動生成功能。 生產環境 (Production) 最安全,無風險。資料庫結構需由 DBA 或遷移工具管理。
validate 驗證。應用程式啟動時,Hibernate 會檢查你的 Java Entity 和資料庫的資料表結構是否一致,如果不一致就會拋出異常,阻止應用程式啟動。 生產環境、測試環境 安全。能及早發現模型與資料庫不一致的問題。
update 更新。啟動時,Hibernate 會比較 Entity 和資料表,如果資料表不存在或缺少欄位,它會自動新增 開發環境 (Development) 中等。它不會處理欄位改名或刪除,可能導致資料庫結構髒亂。
create 建立。每次應用程式啟動時,都會刪除所有舊的資料表,然後重新建立 快速原型開發、自動化測試 極高!所有資料都會遺失! 絕對不能在正式環境使用。
create-drop 建立並刪除。應用程式啟動時建立資料表,正常關閉時刪除資料表。 整合測試、特定情境的 Demo 極高! 與 create 風險相同。
  • spring.jpa.show-sql
    • 一個非常實用的除錯工具。設定為 true 後,每次 JPA 執行資料庫操作時,都會在主控台(Console)印出它實際執行的 SQL 語法。
    • spring.jpa.show-sql=true
    • 為了讓輸出的 SQL 更易讀,可以搭配以下設定:
    • spring.jpa.properties.hibernate.format_sql=true

補充資訊

DB 相關安裝教學

關於資料庫相關安裝教學,你可以參考及挑選以下其中一套資料庫教學影片,依影片內容練習來自行安裝:

DB 相關設定

  1. MySQL 資料庫設定

Maven 依賴 (Dependency)

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-j</artifactId>
    <version>9.0.0</version> <!-- 建議使用最新版本 -->
    <scope>runtime</scope>
</dependency>

📌 MySQL Connector/J 在新版 Maven Central 裡 artifactId 改成 mysql-connector-j,舊的 mysql-connector-java 仍可用但已被取代。

application.properties

# --- MySQL 資料庫設定 ---

# MySQL 的連線 URL 格式:
# jdbc:mysql://<主機名稱或IP>:<埠號>/<資料庫名稱>
# localhost:3306 是 MySQL 的預設主機和埠號
spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase?useSSL=false&serverTimezone=UTC

# MySQL 的登入帳號與密碼
spring.datasource.username=myuser
spring.datasource.password=mypassword

# Hibernate 方言 (Dialect),讓 JPA 知道要產生 MySQL 語法
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect
  1. SQL Server 資料庫設定

Maven 依賴 (Dependency)

<dependency>
    <groupId>com.microsoft.sqlserver</groupId>
    <artifactId>mssql-jdbc</artifactId>
    <version>12.8.1.jre11</version> <!-- 選擇對應 JDK 版本的驅動 -->
    <scope>runtime</scope>
</dependency>

📌 請根據你使用的 Java 版本選擇對應的 jre8jre11jre17 版本。

application.properties

# --- SQL Server 資料庫設定 ---

# SQL Server 的連線 URL 格式:
# jdbc:sqlserver://<主機名稱或IP>:<埠號>;databaseName=<資料庫名稱>
# localhost:1433 是 SQL Server 的預設主機和埠號
spring.datasource.url=jdbc:sqlserver://localhost:1433;databaseName=mydatabase

# SQL Server 的登入帳號與密碼
spring.datasource.username=myuser
spring.datasource.password=mypassword

# Hibernate 方言 (Dialect),讓 JPA 知道要產生 SQL Server 語法
spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.SQLServerDialect
  1. 三種資料庫對照表 (PostgreSQL、MySQL、SQL Server)
資料庫 預設埠號 驅動程式依賴 URL 格式範例 Hibernate Dialect
PostgreSQL 5432 org.postgresql:postgresql jdbc:postgresql://localhost:5432/mydatabase PostgreSQLDialect
MySQL 3306 mysql:mysql-connector-j jdbc:mysql://localhost:3306/mydatabase?useSSL=false&serverTimezone=UTC MySQL8Dialect
SQL Server 1433 com.microsoft.sqlserver:mssql-jdbc jdbc:sqlserver://localhost:1433;databaseName=mydatabase SQLServerDialect

相關資料來源


上一篇
Day22 - Spring Boot Web 篇:處理其他類型的請求資訊
下一篇
Day24 - Spring Data JPA 實戰:從 0 到 1 打造 Entity 與 Primary key 設計
系列文
spring boot 3 學習筆記30
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言