Liquibase

LiquiBase是一個用於數據庫重構和遷移的開源工具,經過日誌文件的形式記錄數據庫的變動,而後執行日誌文件中的修改,將數據庫更新或回滾到一致的狀態。LiquiBase的主要特色有:html

  • 支持幾乎全部主流的數據庫,如MySQL, PostgreSQL, Oracle, Sql Server, DB2等;
  • 支持多開發者的協做維護;
  • 日誌文件支持多種格式,如XML, YAML, JSON, SQL等;
  • 支持多種運行方式,如命令行、Spring集成、Maven插件、Gradle插件等;

 

changelog文件格式java

changelog是LiquiBase用來記錄數據庫的變動,通常放在CLASSPATH下,而後配置到執行路徑中。
changelog支持多種格式,主要有XML/JSON/YAML/SQL,其中XML/JSON/YAML除了具體格式語法不一樣,節點配置很相似,SQL格式中主要記錄SQL語句,這裏僅給出XML格式和SQL格式的示例,更多的格式示例請參考文檔mysql

changelog.xmlgit

<changeSet author="admin" id="1496901181769-1">
    <createTable schemaName="ihome" tableName="test">
        <column autoIncrement="true" name="id" type="INT">
            <constraints primaryKey="true"/>
        </column>
        <column name="name" type="VARCHAR(10)"/>
    </createTable>
</changeSet>

 

changelog.sqlgithub

--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';

 

在執行changelog的時候,會在數據庫記錄執行記錄,主要用了下面的兩張表:sql

  1. databasechangelog
  2. databasechangeloglock

 

經常使用的標籤及命令數據庫

1. 標籤app

一個<changeSet>標籤對應一個變動集,由屬性id、name,以及changelog的文件路徑惟一標識。changelog在執行的時候並非按照id的順序,而是按照changeSet在changelog中出現的順序。maven

changelog中的一個changeSet對應一個事務,在changeSet執行完後commit,若是出現錯誤則rollback。ide

 

2. <include>與<includeAll>標籤

<include>的file屬性表示要包含的changelog文件的路徑,這個文件能夠是LiquiBase支持的任意格式,relativeToChangelogFile若是爲true,則表示file屬性表示的文件路徑是相對於根changelog而不是CLASSPATH的,默認爲false。
<includeAll>指定的是changelog的目錄,而不是爲文件,如:

<includeAll path="com/example/changelogs/"/>

 

注意: 目前<include>沒有解決重複引用和循環引用的問題,重複引用還好,LiquiBase在執行的時候能夠判斷重複,而循環引用會致使無限循環,須要注意!

 

3. 生成已有數據庫的changelog

有兩種方式,一種是使用數據庫工具導出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不支持如下功能:存儲過程、函數以及觸發器;

 

生成文件的路徑能夠設置:

<plugin>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-maven-plugin</artifactId>
    <version>3.4.2</version>
    <configuration>
        <propertyFile>src/main/resources/liquibase.properties</propertyFile>
        <propertyFileWillOverride>true</propertyFileWillOverride>
        <!--生成文件的路徑-->
        <outputChangeLogFile>src/main/resources/changelog_dev.xml</outputChangeLogFile>
    </configuration>
</plugin>

 

也能夠配置在properties文件中:

changeLogFile=src/main/resources/db/changelog/db.changelog-master.xml
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?characterEncoding=UTF-8&useSSL=false&jdbcCompliantTruncation=false
username=root
password=123456
verbose=true
## 生成文件的路徑
outputChangeLogFile=src/main/resources/changelog_dev.xml

 

 

Maven集成

liquibase-maven-plugin的配置

若是須要在父項目中配置子項目共享的LiquiBase配置,而各個子項目能夠定義本身的配置,並覆蓋父項目中的配置,則只須要在父項目的pom中將propertyFileWillOverride設置爲true便可,如:

<plugin>
    <groupId>org.liquibase</groupId>
    <artifactId>liquibase-maven-plugin</artifactId>
    <version>3.4.2</version>
    <configuration>
        <propertyFileWillOverride>true</propertyFileWillOverride>
        <propertyFile>src/main/resources/liquibase.properties</propertyFile>
    </configuration>
</plugin>
## 執行changelog中的變動
liquibase:update

## rollback
liquibase:rollback

rollback有3中形式,分別是:
- rollbackCount: 表示rollback的changeset的個數;
- rollbackDate:表示rollback到指定的日期;
- rollbackTag:表示rollback到指定的tag,須要使用LiquiBase在具體的時間點打上tag;

liquibase:rollback -Dliquibase.rollbackCount=3

rollbackDate須要注意日期的格式,必須匹配當前平臺上執行DateFormat.getDateInstance()獲得的格式,好比個人格式爲MMM d, yyyy,示例如:
liquibase:rollback -Dliquibase.rollbackDate="Apr 10, 2016"

rollbackTag使用tag標識,因此須要先打tag,示例如:
liquibase:tag -Dliquibase.tag=tag20160410

而後rollback到tag20160410,如:
liquibase:rollback -Dliquibase.rollbackTag=tag20160410

 

最佳實踐

1. 如何管理changeLogs

按照主要的release版本號管理你的changeLogs

com
  example
    db
      changelog
        db.changelog-master.xml
        db.changelog-1.0.xml
        db.changelog-1.1.xml
        db.changelog-2.0.xml
      DatabasePool.java
      AbstractDAO.java

 

db.changelog-master.xml

該文件包含了全部的release版本的changeLog,並按照正確的順序引入進來:

<?xml version="1.0" encoding="UTF-8"?> 
<databaseChangeLog
  xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
                      http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd">

  <include file="com/example/db/changelog/db.changelog-1.0.xml"/> 
  <include file="com/example/db/changelog/db.changelog-1.1.xml"/> 
  <include file="com/example/db/changelog/db.changelog-2.0.xml"/> 
</databaseChangeLog> 

 

 

2. Managing Stored Procedures
Try to maintain separate changelog for Stored Procedures and use runOnChange=」true」. This flag forces LiquiBase to check if the changeset was modified. If so, liquibase executes the change again.

 

 

3. One Change per ChangeSet
As far as possible, Avoid multiple changes per changeset to avoid failed autocommit statements that can leave the database in an unexpected state

4. ChangeSet Ids
Choose what works for you. Some use a sequence number starting from 1 and unique within the changelog, some choose a descriptive name (e.g. ‘new-address-table’).

5. Document ChangeSets
Use <comments> in the change sets. They say 「A stitch in time saves nine!」

6. Always think about rollback
Try to write changesets in a way that they can be rolled back. e.g. use relevant change clause instead of using custom <sql> tag. Include a <rollback> clause whenever a change doesn’t support out of box rollback. (e.g. <sql>, <insert>, etc)

7. Reference Data Management
Leverage Liquibase to manage your Reference Data. Environment separation (DEV, QA, PROD) can be achieved using 「context」. 

8. Procedure for the developer

  • Using your favorite IDE or editor, create a new local changeSet containing the change;
  • Run Liquibase to execute the new changeSet (this tests the SQL code);
  • Perform the corresponding changes in the application code (e.g., Java code);
  • Test the new application code together with the database change;
  • Commit both the changeSet and the application code.

 

 

問題

'changeLogFile' in properties file is not being used by this task.

 

 

連接

相關文章
相關標籤/搜索