[Liquibase]配置文件詳解

大致搜了下liquibase的使用,所有人都是寫的怎麼簡單使用,給個示例就完結了,10個人的文章,9個人抄1個人的,沒有人寫怎麼使用的詳細文檔。只能找下官方文檔,做了一些驗證和整理,方便想要學習瞭解liquibase的英文不好的學習者。

數據庫更改日誌文件

即databaseChangeLog文件,Liquibase入口文件。這個文件裏可以引入你的版本修改文件,執行順序爲從上到下。
示例(XML):

<?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"
    xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
    xmlns:pro="http://www.liquibase.org/xml/ns/pro"
    xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd
    http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd
    http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-3.8.xsd ">
</databaseChangeLog>

可以用include引入其他版本修改歷史文件,如下圖:
在這裏插入圖片描述
嚴格來說,其實存在四種格式,XMLYAMLJSONSQL

同XML格式相同含義的YAML格式文件可以表示爲:

databaseChangeLog:

JSON格式:

{
    "databaseChangeLog": [
    ]
}

SQL格式:

--liquibase formatted sql

一、XML格式

tag Description
preConditions 執行sql變更文件的前置條件
property 設置的屬性的值
changeSet 要執行的更改
include 包含要執行的更改集的附加文件
context 上下文將被附加到(使用AND)所有變更集

1.preConditions標籤

可以應用於<databaseChangeLog>標籤或者<changeSet>標籤。
示例:

<?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.8.xsd">
    <preConditions>
        <dbms type="oracle" />
        <runningAs username="SYSTEM" />
    </preConditions>

    <changeSet id="1" author="bob">
        <preConditions onFail="WARN">
            <sqlCheck expectedResult="0">select count(*) from oldtable</sqlCheck>
        </preConditions>
        <comment>Comments should go after preCondition. If they are before then liquibase usually gives error.</comment>
        <dropTable tableName="oldtable"/>
    </changeSet>
</databaseChangeLog>

上述的示例,是只有在Oracle數據庫以及用戶是SYSTEM時纔會執行。

preConditions前置條件分爲正常和異常情況:
正常情況下,無論返回的值是不是預料的值(0),oldtable都會被刪除,只是如果不是預料的值,這裏會給出WARN;
異常情況下,也就是如果oldtable不存在,刪除oldtable的命令將不會執行。

(1)處理失敗和錯誤

Attribute Description
onFail 當preConditions是失敗情形下如何處理
OnError 當preConditions是錯誤情形下如何處理
onSqlOutput 在updateSQL模式下要做什麼
onFailMessage 輸出的失敗信息
onErrorMessage 輸出的錯誤信息
OnFail/OnError值可能配置的值
Value Description
HALT 立即停止執行整個更改日誌。 [默認]
CONTINUE 跳過* changeSet 。 下次更新時將再次嘗試執行更改集。 繼續 changelog *。
MARK_RAN 跳過更改集,但將其標記爲已執行。繼續更改日誌。
WARN 輸出警告並繼續照常執行* changeSet * / * changelog *。
onSqlOutput可能配置的值
Value Description
TEST 在updateSQL模式下運行changeSet
FAIL 使preConditons在updateSQL模式下失敗
IGNORE 忽略updateSQL模式中的preConditons(默認)。

(2)and/or/not邏輯

可以使用nestable <and><or><not>標記將條件邏輯應用於前置條件。如果沒有指定條件標記,則默認爲AND。

示例:

<preConditions onFail="WARN">
    <dbms type="oracle" />
    <runningAs username="SYSTEM" />
</preConditions>

這裏就是默認值AND,也就是同時滿足既是oracle數據庫,並且用戶必須是SYSTEM纔會執行。

如果使數據更改可以在oracle和mysql中可以執行,需要用到or表達式:

 <preConditions>
     <or>
         <dbms type="oracle" />
         <dbms type="mysql" />
     </or>
 </preConditions>

複合條件,例如,是oracle數據庫,並且用戶必須是SYSTEM 或者 數據庫是mysql,且用戶需要爲root時,可以這樣寫:

 <preConditions>
     <or>
         <and>
            <dbms type="oracle" />
            <runningAs username="SYSTEM" />
         </and>
         <and>
            <dbms type="mysql" />
            <runningAs username="root" />
         </and>
     </or>
 </preConditions>

(3)可用的preConditions

  • <dbms>:如果針對指定類型執行的數據庫匹配,則可以傳遞。
<dbms type="mysql" />
  • <runningAs>:執行執行的用戶,匹配纔可以傳遞。
<runningAs username="root" />
  • <changeSetExecuted>:如果指定的changeSet被執行了纔可以傳遞。
<changeSetExecuted id="1" author="YoungLu" changeLogFile="classpath:liquibase/changelog/2020-02-11-change.xml" />
  • <columnExists>:如果數據庫中的指定列存在則傳遞
<columnExists schemaName="young_webchat" tableName="y_user" columnName="username" />
  • <tableExists>:如果數據庫中的表存在,則傳遞
<tableExists schemaName="young_webchat" tableName="y_user" />
  • <viewExists>:如果數據庫中的視圖存在,則傳遞
<viewExists schemaName="young_webchat" viewName="y_user_view" />
  • <foreignKeyConstraintExists>:如果外鍵存在則傳遞
<foreignKeyConstraintExists schemaName="young_webchat" foreignKeyName="y_user_log_fk" />
  • <indexExists>:如果索引存在則傳遞
<indexExists schemaName="young_webchat" indexName="y_user_idx" />
  • <sequenceExists>:如果序列存在則傳遞
<sequenceExists schemaName="young_webchat" sequenceName="y_user_seq" />
  • <primaryKeyExists>:如果主鍵存在則傳遞
<primaryKeyExists schemaName="young_webchat" primaryKeyName="y_user_id" />
  • <sqlCheck>:執行SQL檢查。SQL必須返回具有單個值的單個行。
<sqlCheck expectedResult="1">SELECT COUNT(1) FROM pg_tables WHERE TABLENAME = 'myRequiredTable'</sqlCheck>
  • <changeLogPropertyDefined>:檢查給定的changelog參數是否存在。如果一個值也是給定的,如果這個值與給定的值不相同那麼它只會失敗。
<changeLogPropertyDefined property="myproperty"/>
<changeLogPropertyDefined property="myproperty" value="requiredvalue"/>
  • <customPrecondition>:可以通過創建實現liquibase.precondition的類來創建自定義前置條件。CustomPrecondition接口。自定義類的參數是通過基於子標記的反射設置的。參數作爲字符串傳遞給自定義前置條件。
<customPrecondition className="com.example.CustomTableCheck">
    <param name="tableName" value="our_table"/>
    <param name="count" value="42"/>
</customPrecondition>

2.Properties標籤

爲changelog定義一個參數。給定上下文 和/或 數據庫的列表,該參數將僅在這些上下文 和/或 數據庫中使用。

示例:

<databaseChangeLog
        xmlns="http://www.liquibase.org/xml/ns/dbchangelog"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:ext="http://www.liquibase.org/xml/ns/dbchangelog-ext"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd
        http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">

    <property name="clob.type" value="clob" dbms="oracle"/>
    <property name="clob.type" value="longtext" dbms="mysql"/>

    <changeSet id="1" author="joe">
         <createTable tableName="${table.name}">
             <column name="id" type="int"/>
             <column name="${column1.name}" type="${clob.type}"/>
             <column name="${column2.name}" type="int"/>
         </createTable>
    </changeSet>
</databaseChangeLog>

可用的配置項

Attribute Description
name 表的數據庫名稱
value 所需列的表的名稱
context 上下文,逗號分隔
dbms 要用於該changeSet 的數據庫的類型。關鍵字all和none也可用。
global 定義屬性是全局的還是侷限於databaseChangeLog。“true”或“false”。

示例:

<property name="simpleproperty" value="somevalue"/>
<property name="clob.type" value="clob" dbms="oracle,h2"/>
<property name="clob.type" value="longtext" dbms="mysql"/>
<property name="myproperty" value="yes" context="common,test"/>
<property name="localproperty" value="foo" global="false"/>

3. changeSet標籤

將一個個數據庫更改分開。

示例:

<?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"
  xmlns:pro="http://www.liquibase.org/xml/ns/pro"
  xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.8.xsd
      http://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-3.8.xsd">
    <changeSet id="1" author="bob">
        <comment>A sample change log</comment>
        <createTable/>
    </changeSet>
    <changeSet id="2" author="bob" runAlways="true">
        <alterTable/>
    </changeSet>
    <changeSet id="3" author="alice" failOnError="false" dbms="oracle">
        <alterTable/>
    </changeSet>
    <changeSet id="4" author="alice" failOnError="false" dbms="!oracle">
        <alterTable/>
    </changeSet>

</databaseChangeLog>

一般主要由“id” 、“author”、changelog文件路徑名組成

(1)可用的屬性值:

屬性 描述
id 唯一識別,不一定是數字
author 作者
dbms 數據庫類型
runAlways 在每次運行時執行changeset ,即使之前已經運行過
runOnChange 在第一次看到更改時執行更改,並且在每次changeset 時執行更改
context 控制是否執行changeset,這取決於運行時設置。任何字符串都可以用於上下文名稱,它們被不區分大小寫地選中。
labels 控制是否執行changeset,這取決於運行時設置。任何字符串都可以用於標籤名稱,並且不區分大小寫地選中它們。
runInTransaction 是否應該將changeset作爲單個事務運行(如果可能的話)?默認值爲true。
failOnError 如果在執行changeset時發生錯誤,遷移是否應該失敗
objectQuotingStrategy 這控制了在生成的SQL中如何引用對象名,或者在對數據庫的調用中如何使用對象名。不同的數據庫對對象的名稱執行不同的操作,例如Oracle將所有內容都轉換爲大寫(除非使用引號)。有三個可能的值。默認值是LEGACY。三個配置的值: LEGACY - Same behavior as in Liquibase 2.0 QUOTE_ALL_OBJECTS - 每個對象都加上雙引號 :person becomes “person”.QUOTE_ONLY_RESERVED_WORDS - 在保留關鍵字和可用列名上面加雙引號

(2)可用的子標籤

value description
comment 註釋
preConditions 前置條件,例如做一些不可逆操作前的必要檢查
<Any Refactoring Tag(s)> 要作爲這個更改集的一部分運行的數據庫更改
validCheckSum 添加一個校驗和,不管數據庫中存儲了什麼,它都被認爲對這個changeset是有效的。主要用於需要更改changeset,並且不希望在已經運行了changeset的數據庫上拋出錯誤(不推薦使用此過程)
rollback 描述如何回滾更改集的SQL語句或重構標記

着重講一下rollback標籤的示例:

<changeSet id="1" author="bob">
    <createTable tableName="testTable">
    <rollback>
        drop table testTable
    </rollback>
</changeSet>
<changeSet id="1" author="bob">
    <createTable tableName="testTable">
    <rollback>
        <dropTable tableName="testTable"/>
    </rollback>
</changeSet>
<changeSet id="2" author="bob">
    <dropTable tableName="testTable"/>
    <rollback changeSetId="1" changeSetAuthor="bob"/>
</changeSet>

這裏發生了回滾,會調用id爲1的changeSet 。

4.include標籤

將change-logs拆分爲易於管理的部分。

例如:

<?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.8.xsd">
    <include file="com/example/news/news.changelog.xml"/>
    <include file="com/example/directory/directory.changelog.xml"/>
</databaseChangeLog>

可用的配置項:

Attribute Description
file 被引入的文件
relativeToChangelogFile 用文件的相對路徑而不是classpath
context 向所有包含的changeSets追加上下文(使用AND)

二、sql格式(2.0以後支持)

每一個sql文件都以--liquibase formatted sql開頭。
一個SQL格式的changeSet範例:

--liquibase formatted sql

--changeset nvoxland:1
create table test1 (
    id int primary key,
    name varchar(255)
);
--rollback drop table test1;

--changeset nvoxland:2
insert into test1 (id, name) values (1, ‘name 1);
insert into test1 (id, name) values (2, ‘name 2);

--changeset nvoxland:3 dbms:oracle
create sequence seq_test;

1.Changesets

格式化的SQL文件中的每個changeSets都以表單的註釋開始:

--changeset author:id attribute1:value1 attribute2:value2 [...]

changeset 註釋後面是一個或多個SQL語句,用分號(或屬性的值)分隔。

可用的屬性值

Attribute Description
stripComments 執行sql前去除所有註釋去執行,默認爲true
splitStatements 設置爲false,表示沒有liquibase分割語句 ; 和 GO 。如果未設置,則默認爲true
rollbackSplitStatements 同上,但用於回滾的SQL
endDelimiter 結束的分隔符,默認 ;
runAlways 每次運行都執行該SQL
rollbackEndDelimiter 回滾的結束分隔符
runOnChange 修改後每次都執行
context 如果在運行時傳遞了特定的上下文,則執行更改。任何字符串都可以用於上下文名稱,它們被不區分大小寫地選中。
logicalFilePath 用於在創建chageSet的唯一標識符時重寫文件名和路徑。在移動或重命名更改日誌時需要。
labels 標籤用於對changeSet分類
runInTransaction 默認爲true。changeSet是否運行在一個事務裏面
failOnError 如果在執行變更集時發生錯誤,遷移是否應該失敗
dbms 用於該changeSet的數據庫
logicalFilePath 設置databasechangelog表中的邏輯文件路徑,而不是執行liquibase的sql的物理文件位置。

2.Preconditions

--preconditions onFail:HALT onError:HALT
--precondition-sql-check expectedResult:0 SELECT COUNT(*) FROM my_table

運行changeSet的前置條件,可參考上面xml的說明。

3.Rollback

--rollback SQL STATEMENT

回滾。

4.Comment

--comment: Some comment

註釋

5.Valid CheckSum

校驗和,不管數據庫中存儲的是什麼,它都被認爲對這個changeSet有效。主要用於當您需要更改更改集,並且不希望在已經運行該更改集的數據庫上拋出錯誤(不推薦使用此過程)時(這個不是很明白)
在這裏插入圖片描述

--validCheckSum: 3:098f6bcd4621d373cade4e832627b4f6
--validCheckSum: 7:ad0234829205b9033196ba818f7a872b

6.Ignore lines

允許忽略一些行。 與其他SQL工具一起使用同一腳本時很有用。

--changeset author:id1
CREATE OR REPLACE PACKAGE ...
--ignoreLines:2
/
show errors;
--changeset author:id2
CREATE OR REPLACE PACKAGE BODY ...

也可以用start和end標註:

--changeset author:id1
CREATE OR REPLACE PACKAGE ...
--ignoreLines:start
/
show errors;
--ignoreLines:end
--changeset author:id2
CREATE OR REPLACE PACKAGE BODY ...
發佈了48 篇原創文章 · 獲贊 5 · 訪問量 4萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章