昨天的 Day 13,我們終於讓智慧健康助理加入了第一個資料紀錄功能:每日飲水量紀錄!
使用者可以透過 POST API 新增飲水量,再透過 GET API 查詢累積總量。
例如:
{
"amount": 300
}
新增後,系統就會把飲水量儲存在 Java 的 List 裡面。
不過昨天也發現一個問題:
只要重新啟動 Spring Boot,原本的飲水紀錄就全部消失了!
如果只是練習 Java,這樣其實沒什麼問題。
但如果未來真的想把智慧健康助理當成日常健康管理工具,總不能每次重新啟動程式,就要重新輸入所有資料吧 XD
所以今天決定開始認識資料庫!
今天的目標是:
了解資料庫的基本概念,並讓 Spring Boot 第一次連接 H2 Database,為之後儲存健康紀錄做準備。
昨天我們使用:
List<Integer> waterRecords = new ArrayList<>();
儲存飲水紀錄。
例如:
[300, 500, 250]
這樣可以成功計算:
300 + 500 + 250 = 1050 ml
但是 List 裡面的資料是儲存在程式執行時使用的記憶體中。
當程式停止後,這些資料就不會繼續保留。
所以如果想讓健康紀錄可以長期保存,就需要另外的儲存方式。
這時候就可以使用資料庫。
簡單來說:
資料庫可以幫助我們有系統地儲存、查詢和管理資料。
例如未來可能需要記錄:
如果全部都只放在 Java 的 List 裡面,後續管理就會越來越困難。
先用簡單的表格比較:
| 比較項目 | Java List | 資料庫 |
|---|---|---|
| 主要用途 | 程式執行時管理資料 | 儲存與管理資料 |
| 重新啟動 | 資料通常消失 | 可依儲存方式保留 |
| 查詢功能 | 需要自己寫程式 | 可以使用查詢語法 |
| 大量資料 | 不適合全部長期放在記憶體 | 較適合持續管理 |
| 多筆紀錄 | 可以 | 可以 |
| 長期健康紀錄 | 不太適合 | 較適合 |
不過要注意,並不是所有資料庫都會自動永久保存資料。
例如今天要使用的 H2,就可以選擇記憶體模式或檔案模式。
如果使用記憶體模式,重新啟動程式後,資料一樣會消失。
所以今天也會特別認識這兩種模式的差別。
今天選擇使用的是:
H2 Database
H2 是一種以 Java 開發的關聯式資料庫。
它的特色是輕量、容易整合,也很適合用來學習 Spring Boot 的資料庫操作。
相較於一開始就安裝 MySQL 或 PostgreSQL,H2 的設定通常比較簡單。
對目前這個 Side Project 來說,我覺得很適合先拿來練習。
H2 常見的使用方式包括:
資料儲存在記憶體中。
例如:
spring.datasource.url=jdbc:h2:mem:healthdb
優點是啟動快速、設定簡單。
但當資料庫結束運作後,資料就不會保留。
資料儲存在檔案中。
例如:
spring.datasource.url=jdbc:h2:file:./data/healthdb
這樣資料庫就可以將資料寫入專案目錄下的檔案。
在正常關閉並重新啟動程式後,資料通常可以繼續保留。
因為我們希望健康紀錄不要每次重新啟動就消失,所以今天決定使用:
H2 File Mode!
在開始設定之前,先了解資料庫最基本的概念。
關聯式資料庫通常使用 Table(資料表)來儲存資料。
可以把 Table 想成一個有欄位和資料列的表格。
例如飲水紀錄:
| id | amount | record_date |
|---|---|---|
| 1 | 300 | 2026-10-17 |
| 2 | 500 | 2026-10-17 |
| 3 | 250 | 2026-10-17 |
這裡有三個欄位:
id
amount
record_date
分別代表:
id:每筆紀錄的識別編號amount:飲水量record_date:紀錄日期每一列則代表一筆飲水紀錄。
例如:
id = 1
amount = 300
record_date = 2026-10-17
就是一筆完整的資料。
之後如果想查詢某一天的飲水量,就可以透過資料庫查詢這些紀錄。
既然要使用關聯式資料庫,就不能不認識 SQL。
SQL 的全名是:
Structured Query Language
中文稱為「結構化查詢語言」。
它可以用來操作關聯式資料庫。
例如新增資料:
INSERT INTO water_records (amount, record_date)
VALUES (300, '2026-10-17');
查詢資料:
SELECT * FROM water_records;
刪除資料:
DELETE FROM water_records
WHERE id = 1;
如果想計算某一天的飲水總量,也可以使用:
SELECT SUM(amount)
FROM water_records
WHERE record_date = '2026-10-17';
這樣資料庫就會幫我們加總指定日期的飲水量。
是不是和昨天使用 Java 的 for 迴圈有點不同?
昨天是把 List 裡面的資料拿出來計算。
今天開始,我們可以讓資料庫協助管理與查詢資料。
接下來正式開始設定專案。
首先打開:
pom.xml
在 <dependencies> 裡加入 H2 Database:
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
因為今天也會使用 Spring Boot 的資料庫相關功能,所以再加入:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
這裡使用的是 Spring JDBC。
它可以讓 Java 程式透過 JDBC 與資料庫溝通。
加入後,記得重新載入 Maven 專案。
目前先不用急著寫複雜的資料庫程式。
今天的重點是讓 Spring Boot 成功連接 H2。
接下來打開:
src/main/resources/application.properties
加入:
spring.application.name=health-assistant
spring.datasource.url=jdbc:h2:file:./data/healthdb
spring.datasource.driver-class-name=org.h2.Driver
spring.datasource.username=sa
spring.datasource.password=
spring.h2.console.enabled=true
spring.h2.console.path=/h2-console
這裡有幾個設定需要了解。
spring.datasource.url=jdbc:h2:file:./data/healthdb
這代表我們使用 H2 的檔案模式。
其中:
./data/healthdb
表示資料庫檔案的位置。
相對路徑會依照程式啟動時的工作目錄解析。
spring.datasource.username=sa
這是 H2 練習環境常見的預設帳號。
spring.datasource.password=
這裡暫時使用空密碼,方便本機練習。
但正式部署時不能直接沿用這種設定。
spring.h2.console.enabled=true
這個設定會啟用 H2 Console。
我們就可以透過瀏覽器查看資料庫。
不過 H2 Console 主要是開發工具,不適合直接對外公開。
設定完成後,重新啟動 Spring Boot。
如果資料庫設定沒有問題,Spring Boot 就可以建立與 H2 的連線。
接著打開瀏覽器:
http://localhost:8080/h2-console
應該會看到 H2 Console 的登入畫面。
登入資訊設定為:
JDBC URL:
jdbc:h2:file:./data/healthdb
User Name:
sa
Password:
密碼保持空白。
確認 JDBC URL 和 application.properties 裡面的設定一致。
接著按下:
Connect
如果連線成功,就可以進入 H2 Console。
這代表我們已經成功讓 Spring Boot 專案連接資料庫了!
接下來先試著建立一張飲水紀錄資料表。
在 H2 Console 輸入:
CREATE TABLE IF NOT EXISTS water_records (
id BIGINT GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY,
amount INT NOT NULL,
record_date DATE NOT NULL
);
這裡出現幾個新的 SQL 語法。
CREATE TABLE
代表建立資料表。
PRIMARY KEY
代表主鍵,用來識別每一筆資料。
NOT NULL
代表欄位不能是 NULL。
DATE
代表日期型別。
這樣我們就建立了一張簡單的飲水紀錄資料表。
目前包含:
id
amount
record_date
三個欄位。
資料表建立完成後,接下來試著新增資料。
在 H2 Console 輸入:
INSERT INTO water_records (amount, record_date)
VALUES (300, CURRENT_DATE);
這裡使用:
CURRENT_DATE
代表資料庫目前的日期。
再新增一筆:
INSERT INTO water_records (amount, record_date)
VALUES (500, CURRENT_DATE);
現在資料表裡應該已經有兩筆飲水紀錄。
接著輸入:
SELECT * FROM water_records;
就可以查看資料。
預期會看到類似:
ID | AMOUNT | RECORD_DATE
1 | 300 | 2026-10-17
2 | 500 | 2026-10-17
實際日期會依照執行當天的資料庫日期顯示。
這也是第一次真正把飲水紀錄放進資料庫裡!
昨天我們使用 Java 的:
for
迴圈計算飲水總量。
今天則可以直接使用 SQL:
SELECT SUM(amount)
FROM water_records
WHERE record_date = CURRENT_DATE;
假設今天新增了:
300 ml
500 ml
查詢結果就會是:
800
如果想讓查詢結果更容易理解,可以加入別名:
SELECT SUM(amount) AS total_water
FROM water_records
WHERE record_date = CURRENT_DATE;
這樣查詢結果的欄位名稱就會變成:
TOTAL_WATER
這讓我發現,資料庫不只是拿來儲存資料,也可以協助我們進行資料查詢和簡單的統計。
接下來要測試今天最重要的事情:
重新啟動 Spring Boot,資料會不會消失?
測試步驟:
water_records 裡面有資料。SELECT * FROM water_records;
如果設定正確,而且使用的是相同的資料庫檔案,就應該還能看到剛剛新增的資料。
這和昨天的 List 有很大的不同。
昨天:
重新啟動
↓
List 清空
↓
資料消失
今天:
資料寫入 H2 檔案
↓
重新啟動
↓
重新連接資料庫
↓
資料仍然存在
不過今天只是透過 H2 Console 手動操作資料庫。
昨天的 WaterService 仍然使用 List,還沒有真正改成從資料庫讀寫資料。
這個部分就留到下一篇繼續完成!
經過今天的調整,專案大致變成:
health-assistant
│
├── src
│ └── main
│ ├── java
│ │ └── com/example/healthassistant
│ │ │
│ │ ├── HealthAssistantApplication.java
│ │ │
│ │ ├── controller
│ │ │ ├── HealthController.java
│ │ │ └── WaterController.java
│ │ │
│ │ ├── service
│ │ │ ├── BmiService.java
│ │ │ └── WaterService.java
│ │ │
│ │ ├── dto
│ │ │ ├── HealthRequest.java
│ │ │ └── WaterRequest.java
│ │ │
│ │ └── exception
│ │ └── GlobalExceptionHandler.java
│ │
│ └── resources
│ └── application.properties
│
├── data
│ └── healthdb.mv.db
│
└── pom.xml
其中:
healthdb.mv.db
是 H2 檔案模式可能建立的資料庫檔案。
實際檔案位置會受到啟動時工作目錄的影響。
另外,資料庫檔案不適合直接提交到公開的 GitHub Repository。
未來如果專案要上傳 GitHub,也要記得將本機資料庫檔案加入 .gitignore。
今天選擇 H2,主要是因為它很適合學習和測試。
但如果未來想把智慧健康助理真正部署成多人使用的系統,就需要考慮其他資料庫。
例如:
| 資料庫 | 常見用途 |
|---|---|
| H2 | 本機開發、測試、小型應用 |
| MySQL | 網站與一般應用系統 |
| PostgreSQL | 網站、資料管理與較複雜的應用 |
目前先使用 H2 就足夠了。
等之後真的需要部署、管理多位使用者,或儲存大量健康紀錄,再考慮改用 MySQL 或 PostgreSQL。
另外,健康資料可能涉及個人隱私。
如果未來要儲存真實使用者的健康資訊,就需要進一步考慮身分驗證、存取權限、加密、備份與資料保護等問題。
所以目前這個專案仍然以練習資料為主。
雖然今天還沒有真正使用 AI,但資料庫其實是後續智慧健康助理的重要基礎。
因為如果未來想讓 AI 協助整理健康紀錄,系統就需要先取得相關資料。
例如:
資料庫
│
├── 每日飲水量
├── 睡眠時間
├── 運動紀錄
└── BMI 紀錄
↓
Java Service
↓
整理必要資料
↓
AI API
↓
產生文字摘要
如果沒有資料庫,系統可能只能處理使用者當下輸入的資料。
但有了資料庫,就可以逐漸累積不同日期的紀錄。
未來也比較容易實作:
查詢最近七天的飲水紀錄
或是:
整理本週睡眠時間變化
不過資料送往外部 AI 服務之前,還需要考慮隱私、使用者同意及資料最小化等問題。
今天先把資料庫的基礎建立起來,之後再慢慢加入 AI 功能。
今天終於開始接觸資料庫!
原本我們使用 Java 的 List 暫時儲存飲水紀錄,但重新啟動後資料就會消失。
所以今天改為認識 H2 Database,並學習如何讓 Spring Boot 連接資料庫。
今天學到的重點包括:
目前我們已經可以透過 H2 Console:
建立資料表
↓
新增飲水紀錄
↓
查詢資料
↓
計算累積總量
↓
重新啟動後保留資料
雖然今天還沒有讓 WaterService 直接操作資料庫,但至少已經成功建立資料庫的基礎。
這也是智慧健康助理從單純的 Java 練習,慢慢走向完整應用系統的重要一步!
今天我們已經讓 Spring Boot 成功連接 H2 Database,也透過 H2 Console 手動新增了飲水紀錄。
但目前還有一個問題:
我們的 WaterService 仍然使用 List,並沒有真正將 API 收到的飲水資料寫入資料庫。
所以下一篇準備讓 Java 程式直接操作 H2!
預計會學習:
JdbcTemplate
讓智慧健康助理的飲水紀錄,真正可以透過 API 儲存到資料庫裡!