(17) Spring Boot 導入 Liquibase

Albert Hg
learning-from-jhipster
8 min readJan 7, 2021

上一篇文章我們粗淺的介紹了 Liquibase 的使用目的,而這一篇文章將會把 Liquibase 導入我們的專案中,並且更詳細的介紹到底該怎麼使用他。

Spring Boot 導入 Liquibase

1. 加入 Dependency

要在 Spring Boot 中導入 Liquibase 必須加入如下 Dependency:

<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>

這裡我們不需要指定 Liquibase 使用的 Version 也沒關係,因為在加入 spring-boot-starter-parent 的時候,就已經有將 Liquibase 包含於其中了。

2. 建立 ChangeLog 的主要入口檔案

我們在上一篇文章中有曾經提到下面這段話:

在使用 <databaseChangeLog/> 的時候,為了要達到管理資料庫版本的控管,因此一定會將對應的 <databaseChangeLog/> 寫在不同的擋案中。但 lisquibase 在取得這些擋案時,一定都會有一個入口檔案或主要檔案,而這個檔案就會記錄著每一版 <databaseChangeLog/> 的引入位置與歷程。

所以接著要建立這個 ChangeLog 的主要檔案,這裡有兩種做法:

2-1. 使用 Liquibase 的預設路徑與名稱

classpath:/db/changelog/db.changelog-master.yaml 是 Liquibase 預設所使用的 ChangeLog 的路徑與名稱設定。因此如果決定使用預設路徑的話,就必須在 src/main/db/changelog/ 的路徑中加入 db.changelog-master.yaml 的檔案,並且在這個 YAML 檔中加入如下內容:

https://gist.github.com/albert-hg/ade652393631498a5b207e835a449795

2-2. 使用自定義的路徑與名稱

因為 Spring Boot 已經事先將 Liquibase 的配置整合起來,所以如果不想使用 YAML,想使用 XML,或想要自定義 ChangeLog 的路徑,那麼就可以在設定檔 Properties 的部分進行設定,並在對應路徑建立一個 ChangeLog 的檔案(這裡我們以 master.xml 為 ChangeLog 的檔案名稱作為範例):

https://gist.github.com/albert-hg/8119b11650ec74a2c97a6e3304c137d0

這裡我將設定檔寫在 config/application.yml 中,主要是因為如果沒有特別的需求需要依照「developement」或「production」環境執行不同的 ChangeLog,那麼直接在共用的 application.yml 進行設定即可。

當然這個部分是受惠於 Spring Boot 的整合,所以才可以直接這樣簡單的進行設定。但如果想要使用 Bean 等注入 Configuration 的方式來設定參數,也可以在 src\main\java\...\configuration\ 中加入對應的 Configuration ,如下:

https://gist.github.com/albert-hg/681d3de11b872d18a63f3b14d5032599

這裡的話如果可以兩者擇一,選擇使用 Spring Boot 的 Properties 設定檔,或者使用 Bean 注入 Configuration 的方式來進行設定也可以。

在這個系列文的專案中,我們將選擇使用額外設定 Configuration 的方式進行設定。

3. 執行專案,啟動 Liquibase

當我們把 Liquibase 的 Dependency 加入,並且設定好對應的 ChangeLog 檔案位置後,就可以執行專案,Liquibase 就會在專案啟動的同時,依序執行下列動作:

  • 先檢查資料庫中是否存在 DATABASECHANGELOGDATABASECHANGELOGLOCK 這兩張 Liquibase 所需的表,若不存在則建立
  • 檢查 DATABASECHANGELOGLOCK 的狀態是不是被 Locked,如果是被鎖住的話就代表已經有另外的服務正在使用 Liquibase 使得資料庫不得再由其他 Liquibase 進行操作,否則則 Locked 住當前所指定的資料庫
  • 檢查 DATABASECHANGELOG 表中已經執行過的 ChangeSet 的 MD5SUM 是否和當前所指定的 ChangeLog 中的 ChangeSet 轉換後的 MD5SUM 一樣,這個動作是為了確保之前執行過的 ChangeSet 是沒有被變動過的
  • 檢查完後開始讀取新的 ChangeSet 並執行相關內容、更新資料庫內的 Table 等資訊,再將完成執行的 ChangeSet 紀錄於 DATABASECHANGELOG
  • 執行完所有的 ChangeSet 後,解除 DATABASECHANGELOGLOCK 的鎖,則透過 Liquibase 管理資料庫版本的部分就完成了

因為我們在先前的文章中,已經替 development 環境加入了 H2,所以現在我就可以簡單的用 H2 來進行 Liquibase 的測試,但是在執行專案前,要先注意專案中是否已經有存在舊的 H2DB File,如果有的話,可以將專案中的 target 資料夾中底下的 h2db 資料夾內的內容給移除,以確保環境是乾淨的。

當我們透過 .\mvnw 來執行專案,就可以看到 Log 的部分出現如下內容,也就是上方所述的 「Liquibase 的執行流程」:

https://gist.github.com/albert-hg/531f7cccb675bd8bc8152b55ef7f152b

到此我們就成功的將 Liquibase 導入至我們的 Spring Boot 專案中了。

DATABASECHANGELOG 與 DATABASECHANGELOGLOCK

那麼在我們順利的將 Liquibase 導入後,會發生甚麼事情呢?

首先我們可以進入 H2-Console 的頁面,然後看一下這兩張表的有哪寫內容 (DATABASECHANGELOG 與 DATABASECHANGELOGLOCK 這兩張表的欄位細節說明,可以在上一篇的介紹中找到):

在 DATABASECHANGELOG 中,你可以看到裡面沒有任何資料,這是很正常的,因為目前還沒有在 ChangeLog 中加入任何會修改資料庫的 ChangeSet,例如新增表、新增欄位、修改欄位、刪除表、刪除欄位等動作。在下一篇文章中我們才會開始加入這些內容。

而在 DATABASECHANGELOGLOCK 中,只會有一列資料,如同上一篇文章中所介紹的,Liquibase 在這張表中只會有這一列資料,用來記錄當前是否有 Liquibase 正在使用資料庫、修改 Table,如果有的話,那麼在 Locked 的欄位中就會是 True,反之就是 False。

Liquibase 的其他 Spring Boot Properties 相關設定

在 Spring Boot 的 Properties 設定檔中,除了可以設定如上所述的 spring.liquibase.change-log 之外,其實還有許多跟 Liquibase 的參數可以進行設定,你可以參考: Spring Boot Properties — Data Migration 的部分,就可以找到與 Liquibase 相關的設定內容。

這邊簡單的做個整理,將其轉換成 YAML 格式並加上說明供你參考:

https://gist.github.com/albert-hg/d28d240d1487ed7438e36cba94bf1cd7

文末

到這裡我們已經將 Liquibase 導入至專案中,並詳細介紹了將 Liquibase 導入至專案的步驟,且針對細節進行說明。

而正式透過 Liquibase 對資料庫進行修改的部分,則會在下一篇詳細介紹。包含我們可能要完成怎樣的專案,資料庫中應該有哪些表,以及 ChangeSet 的使用介紹與說明 (所以下一篇的內容應該會很多XD)。

那麼就接著看下去吧~!

--

--

Albert Hg
learning-from-jhipster

I am a programmer but love other things. I am a nobody but keep myself going. I am a person who wishes to reach the heaven but lost the wings.