使用Liquibase將資料庫加入版本管理
主題: |
使用Liquibase將資料庫加入版本管理 |
文章簡介: |
介紹Liquibase套件,透過範例,初步了解其使用方式, 執行資料庫指令並將歷程記錄至資料表中, 以達到資料表內容版本管理的功能。 |
作者: |
江直穎 |
版本/產出日期: |
V1.0/2016.11.08 |
1. 前言
• 本文件用來提供Java開發者在開發應用程式時透過Liquibase套件,
執行資料庫指令並將歷程記錄至資料表中,以達到資料表內容版本管理的功能。
• 開發工具使用IntelliJ IDEA 15 Communication Edition, 以下簡稱IntelliJ。
2. 目的
• 初步了解Liquibase 並透過changeLog設定執行資料庫命令並記錄歷程。
• 了解如何利用Maven 執行Liquibase。
3. 開始前準備
本架構建立於以下版本的環境:
• JDK8
• Liquibase 3.4.2
• MySQL 5.1
• Maven3.2.2
4. 認識Liquibase
簡介
Liquibase是一套執行在JAVA環境的資料庫版本管理工具,
主要是開發時期資料庫schema的建立構成(如Create Table,Add column ,Index 等…)
資料內容的異動(insert,update,delete) 並透過Liquibase標籤語法撰寫xml檔案,
最後定義各個changeSet變更集,執行更改資料庫的異動。
在執行時期,於資料庫裡會自動建立一個名為DATABASECHANGELOG資料表,
以保留在開發與維護時期對於資料庫異動記錄的歷程。
主要概念
依照Liquibase官方網站文件說明,使用Liquibase開發時有五種基本概念:
4.1、 Changelog file(變更歷程檔案):
使用Liquibase與資料庫溝通的主要部分,開發人員將資料庫變更之歷程
存放在本機端的文字檔案,依據databaseChangeLog 內容的設定來對資料庫
執行SQL指令操作,以達到版本控管的功效。
4.2、 Change Set (變更集) :
透過定義其id 與 author屬性作為更改歷程的”唯一標識”,為Liquibase追蹤歷程的執行單位。
執行時期Liquibase會透過changeSet 查詢DATABASECHANGELOG資料表,
查詢標記已執行的變更集,然後處理尚未執行的changeLog中所有的變更集。
4.3、 Changes (變更項目) :
每個變更集通常包含描述要應用於資料庫的更改/重構,除了Liquibase支援
可對資料庫操作的定義標籤外,也可使用資料庫原生SQL Script 對資料庫做更改。
通常建議每個變更集應該只有一個變更項目,以避免可能使資料庫處於意外狀態的
自動提交的失敗。
下圖說明為Liquibase 所支援的資料庫變更/重構動作
4.4、 Preconditions (前提條件) :
可應用於整份ChangeLog 檔案或是指定ChangeSet 前定義”前提條件”區塊。
例如,指定此份ChangeLog 執行的DB Schema , 或在建立Table時檢查
該Table是否存在,或可定義此部份執行失敗則會暫停後續執行SQL指令動作。
下圖說明為Liquibase Precondition可應用的場景
4.5、 Contexts (使用場景標註) :
應用於變更集,可以控制在不同環境中執行不同的變更集。
例如,一些變更集可以標記為“develop”,其他變更集可以標記為“test”
在Liquibase執行期時可以指定要使用哪個context
另外,如果沒有特別指定時,所有未執行過的變更集皆會被正常執行。
5. 範例實作
以下為使用Maven 執行Liquibase 套件解說範例 :
5.1、 建立資料表tp_book
首先定義Maven pom.xml檔案
撰寫一份ChangeLog File : db-changelog-schema.xml
由一組changeSet 標籤來表示一個變更集,並定義變更集標籤(id)與撰寫人員(author)
透過加入createTable標籤中內容,在變更集執行時,從DB建立一個資料表:tp_book
最後將建立資料表欄位名稱與類型以及PK定義填寫於column標籤中,即可完成此變更集
所執行的內容。
另外,如果changeSet 中的id欄位被修改後執行,Liquibase會視此為新增一筆變更命令,
並會再次執行相同動作,可能會造成資料表內容錯誤,此部份在執行時期需要特別注意!
接著透過Maven指令liquibase:update執行建立資料表變更集
輸出log可以發現Liquibase會先判斷DATABASECHANGELOG 資料表內是否有記錄,
若沒有此表格則會自動建立,並執行changeSet中create tp_book Table命令
執行完成後建立相關資料表
檢查tp_book資料表與其欄位皆被正確地建立
查詢DATABASECHANGELOG資料表發現Liquibase自動新增一筆createTable 的
changeSet記錄,其中 id、author、執行時間、執行動作等資訊皆被記錄下來
5.2、 新增資料表內容
撰寫一份ChangeLog File : db-data-process.xml 內容並使用Liquibase Insert標籤
定義insert 標籤並指定資料表名稱(tableName) tp_book
新增的資料內容則使用column標籤指定欄位名稱(name)、內容(value)
可以搭配comment標籤使用為本次變更集註解。
使用include file標籤可以在執行單一changeLogFile時讀取其他changeLogFile
一樣透過Maven指令liquibase:update執行新增資料表資料變更集
可以發現Liquibase執行db-changelog-schema.xml 時也一併執行db-data-process.xml
檔案中的changeSet內容,並寫入兩筆資料至tp_book 資料表中
驗證兩筆資料被正確寫入資料表
查詢DATABASECHANGELOG資料表發現Liquibase自動新增一筆Insert changeSet記錄,
其中 id , author , 執行時間 , 執行動作還有自定義描述資訊Comments皆被記錄下來
5.3、 更新資料表內容
延續撰寫上一份ChangeLog File : db-data-process.xml 內容並使用Liquibase update標籤
其中在update標籤中加入where標籤,如同執行SQL語法,Liquibase會判斷使用者定義
的條件並正確地更新資料表的內容。
執行Maven指令liquibase:update後驗證一筆資料book_price已被更新
查詢DATABASECHANGELOG資料表發現Liquibase自動新增一筆update changeSet記錄
5.4、 使用Context標籤為不同環境建立不同的資料表
修改先前ChangeLog File : db-changelog-schema.xml
將changeSet中加入context屬性欄位,定義onUat & onDev兩種不同執行環境context :
onUat 建立資料表: tp_book 然而onDev建立資料表: test_tp_book
並將db-data-process.xml 檔案加入context修改後並載入執行
接著使用maven指令 :mvn liquibase:update -Dliquibase.contexts="onDev"
執行後於輸出記錄得知只有changeSet : create-testdata-20161201-01
以及changeSet : insert-testdata-20161201-01被Liquibase執行
驗證結果test_tp_book 資料表被正確地建立
驗證資料內容皆正確
執行後新增的兩筆歷程也發現Contexts資訊皆被Liquibase記錄下來
6. 參考來源
• Liquibase 官方網站
http://www.liquibase.org/index.html
• 圖片出處: Brief introduction to Liquibase