LiquiBase是一個用於數據庫重構和遷移的開源工具,經過日誌文件的形式記錄數據庫的變動,而後執行日誌文件中的修改,將數據庫更新或回滾到一致的狀態。html
LiquiBase的主要特色有:java
本文首先簡單介紹一下LiquiBase的changelog文件的經常使用標籤配置,而後介紹在Maven中集成並運行LiquiBase。mysql
changelog是LiquiBase用來記錄數據庫的變動,通常放在CLASSPATH
下,而後配置到執行路徑中。sql
changelog支持多種格式,主要有XML/JSON/YAML/SQL,其中XML/JSON/YAML除了具體格式語法不一樣,節點配置很相似,SQL格式中主要記錄SQL語句,這裏僅給出XML格式和SQL格式的示例,更多的格式示例請參考文檔
數據庫
changelog.xmlmaven
<changeSet id="2" author="daniel" runOnChange="true"> <insert tableName="contest_info"> <column name="id">3</column> <column name="title">title 3</column> <column name="content">content 3</column> </insert> </changeSet>
changelog.sqlide
--liquibase formatted sql --changeset daniel:16040707 CREATE TABLE `role_authority_sum` ( `row_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id', `role_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '關聯role的role_id', `authority_sum` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'perms的值的和', `data_type_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '關聯data_type的id', PRIMARY KEY (`row_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色的權限值的和,如角色有RD權限,則和爲2+8=10';
一個<changeSet>標籤對應一個變動集,由id、name、以及changelog的文件路徑組成惟一標識。changelog在執行的時候並非按照id的順序,而是按照changeSet在changelog中出現的順序。函數
LiquiBase在執行changelog時,會在數據庫中插入兩張表:DATABASECHANGELOG
和DATABASECHANGELOGLOCK
,分別記錄changelog的執行日誌和鎖日誌。工具
LiquiBase在執行changelog中的changeSet時,會首先查看DATABASECHANGELOG
表,若是已經執行過,則會跳過(除非changeSet的runAlways
屬性爲true,後面會介紹),若是沒有執行過,則執行並記錄changelog日誌;ui
changelog中的一個changeSet對應一個事務,在changeSet執行完後commit,若是出現錯誤則rollback;
<changeSet>
標籤的主要屬性有:
DATABASECHANGELOG
表中還記錄了changeSet的MD5校驗值MD5SUM,若是changeSet的id
和name
沒變,而內容變了,則因爲MD5值變了,即便runAlways的值爲True,執行也是失敗的,會報錯。這種狀況應該使用runOnChange
屬性。<changeSet>
下有一個重要的子標籤<rollback>
,即定義回滾的SQL語句。對於create table
, rename column
和add column
等,LiquiBase會自動生成對應的rollback語句,而對於drop table
、insert data
等則須要顯示定義rollback語句。
<include>
與<includeAll>
標籤當changelog文件愈來愈多時,可使用<include>
將文件管理起來,如:
<?xml version="1.0" encoding="utf-8"?> <databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> <include file="logset-20160408/0001_authorization_init.sql" relativeToChangelogFile="true"/> </databaseChangeLog>
<include>
的file屬性表示要包含的changelog文件的路徑,這個文件能夠是LiquiBase支持的任意格式,relativeToChangelogFile若是爲true,則表示file屬性表示的文件路徑是相對於根changelog而不是CLASSPATH的,默認爲false。
<includeAll>
指定的是changelog的目錄,而不是爲文件,如:
<includeAll path="com/example/changelogs/"/>
注意: 目前<include>
沒有解決重複引用和循環引用的問題,重複引用還好,LiquiBase在執行的時候能夠判斷重複,而循環引用會致使無限循環,須要注意!
diff命令用於比較數據庫之間的異同。好比經過命令行執行:
java -jar liquibase.jar --driver=com.mysql.jdbc.Driver \
--classpath=./mysql-connector-java-5.1.29.jar \
--url=jdbc:mysql://127.0.0.1:3306/test \
--username=root --password=passwd \
diff \
--referenceUrl=jdbc:mysql://127.0.0.1:3306/authorization \
--referenceUsername=root --referencePassword=passwd
在已有的項目上使用LiquiBase,要生成當前數據庫的changeset,能夠採用兩種方式,一種是使用數據庫工具導出SQL數據,而後changelog文件以SQL格式記錄便可;另外一種方式就是用generateChangeLog
命令,如:
liquibase --driver=com.mysql.jdbc.Driver \
--classpath=./mysql-connector-java-5.1.29.jar \
--changeLogFile=liquibase/db.changelog.xml \
--url="jdbc:mysql://127.0.0.1:3306/test" \
--username=root \
--password=yourpass \
generateChangeLog
不過generateChangeLog
不支持如下功能:存儲過程、函數以及觸發器;
liquibase-maven-plugin
的配置Maven中集成LiquiBase,主要是配置liquibase-maven-plugin
,首先給出一個示例:
<plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>3.4.2</version> <configuration> <changeLogFile>src/main/resources/liquibase/test_changelog.xml</changeLogFile> <driver>com.mysql.jdbc.Driver</driver> <url>jdbc:mysql://127.0.0.1:3306/test</url> <username>root</username> <password>passwd</password> </configuration> <executions> <execution> <phase>process-resources</phase> <goals> <goal>update</goal> </goals> </execution> </executions> </plugin>
其中<configuration>
節點中的配置能夠放在單獨的配置文件裏。
若是須要在父項目中配置子項目共享的LiquiBase配置,而各個子項目能夠定義本身的配置,並覆蓋父項目中的配置,則只須要在父項目的pom中將propertyFileWillOverride
設置爲true便可,如:
<plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>3.4.2</version> <configuration> <propertyFileWillOverride>true</propertyFileWillOverride> <propertyFile>liquibase/liquibase.properties</propertyFile> </configuration> </plugin>
liquibase:update
執行changelog中的變動:
$ mvn liquibase:update
liquibase:rollback
rollback有3中形式,分別是:
- rollbackCount: 表示rollback的changeset的個數; - rollbackDate:表示rollback到指定的日期; - rollbackTag:表示rollback到指定的tag,須要使用LiquiBase在具體的時間點打上tag;
rollbackCount
比較簡單,示例如:
$ mvn liquibase:rollback -Dliquibase.rollbackCount=3
rollbackDate
須要注意日期的格式,必須匹配當前平臺上執行DateFormat.getDateInstance()
獲得的格式,好比個人格式爲MMM d, yyyy
,示例如:
$ mvn liquibase:rollback -Dliquibase.rollbackDate="Apr 10, 2016"
rollbackTag
使用tag標識,因此須要先打tag,示例如:
$ mvn liquibase:tag -Dliquibase.tag=tag20160410
而後rollback到tag20160410,如:
$ mvn liquibase:rollback -Dliquibase.rollbackTag=tag20160410