使用liquibase-maven-plugin實現持續數據庫集成


數據庫版本管理、持續集成一直都是大家比較關心的問題,網上也有很多相關的文章介紹。一直都很羡慕ruby on railsdatabase migration,非常強大,好在java陣營也有類似的工具可以幫助大家管理數據庫版本,實現數據庫遷移。本文將針對liquibase-maven-plugin這個maven插件做詳細的介紹,希望能對大家有所幫助。

一、配置properties-maven-plugin,使maven加載外部屬性配置文件

liquibase需要配置數據庫的連接屬性及驅動等參數,如果這些參數直接配置在pom文件中,會增加配置管理人員的工作量,因此希望能夠統一讀取web應用中已經配置好的properties文件中的配置屬性,可以使用properties-maven-plugin插件導入配置文件,配置示例如下:

    <plugin>
        <groupId>org.codehaus.mojo</groupId>
        <artifactId>properties-maven-plugin</artifactId>
        <version>1.0-alpha-2</version>
        <executions>
          <execution>
            <phase>initialize</phase>
            <goals>
              <goal>read-project-properties</goal>
            </goals>
            <configuration>
              <files>
                <file>${basedir}/src/main/resources/conf/geoq.properties</file>
              </files>
            </configuration>
          </execution>
        </executions>
    </plugin>

geoq.properties配置示例如下:

    jdbc.driverClassName=org.postgresql.Driver
    jdbc.url=jdbc:postgresql://localhost:5432/geoq_dev
    jdbc.username=postgres
    jdbc.password=4652

那么就可以在pom中使用${PropertyNmae}引用配置屬性,如

    <configuration>
      <changeLogFile>src/main/resources/liquiabse/business_table.xml</changeLogFile>
      <driver>${jdbc.driverClassName}</driver>
      <url>${jdbc.url}</url>
      <username>${jdbc.username}</username>
      <password>${jdbc.password}</password>
    </configuration>

二、配置liquibase-maven-plugin

配置示例如下:

    <plugin>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-maven-plugin</artifactId>
        <version>2.0.5</version>
        <dependencies>
            <dependency>
                <groupId>org.liquibase</groupId>
                <artifactId>liquibase-core</artifactId>
                <version>2.0.5</version>
            </dependency>
        </dependencies>
        <executions>
            <execution>
              <phase>process-resources</phase>
              <configuration>
                    <changeLogFile>src/main/resources/liquiabse/business_table.xml</changeLogFile>
                    <driver>${jdbc.driverClassName}</driver>
                    <url>${jdbc.url}</url>
                    <username>${jdbc.username}</username>
                    <password>${jdbc.password}</password>
              </configuration>
              <goals>
                    <goal>update</goal>
              </goals>
            </execution>
        </executions>
    </plugin>

1、需要通過dependency引入依賴jar包liquibase-core,版本號與插件版本號一致

2、通過phase參數指定何時運行,一般為process-resources

3、changeLogFile參數指定liquibase數據庫變更日志文件

4driverurlusernamepassword配置數據庫連接參數

 三、根據數據庫生成數據庫變更日志文件

針對已有的數據庫,如何產生對應的數據庫變更日志文件,可以使用generateChangeLog指令,使用該指令需要下載liquibase的執行程序,命令示例如下:

    liquibase --driver=org.postgresql.Driver --classpath="C:\Program Files (x86)\PostgreSQL\pgJDBC\postgresql-9.1-901.jdbc4.jar" --changeLogFile=db.changelog.xml --url="jdbc:postgresql://localhost:5432/geoq_dev" --username=postgres --password=4652 generateChangeLog

generateChangeLog默認只會創建數據庫結構的變更日志文件,如果希望創建插入數據的變更日志文件,可以使用參數diffTypes,該參數包括如下可選項:

  • tables [DEFAULT]
  • columns [DEFAULT] 
  • views [DEFAULT]  視圖
  • primaryKeys [DEFAULT]  主鍵
  • indexes [DEFAULT]  索引
  • foreignKeys [DEFAULT] 
  • sequences [DEFAULT]
  • data
    liquibase --driver=org.postgresql.Driver --classpath="C:\Program Files (x86)\PostgreSQL\pgJDBC\postgresql-9.1-901.jdbc4.jar" --changeLogFile=db.changelog.xml --url="jdbc:postgresql://localhost:5432/geoq_dev_full" --username=postgres --password=4652 --diffTypes=data generateChangeLog

比較兩個數據庫:

    liquibase --driver=org.postgresql.Driver --classpath="C:\Program Files (x86)\PostgreSQL\pgJDBC\postgresql-9.1-901.jdbc4.jar" --changeLogFile=db.changelog.xml --url="jdbc:postgresql://localhost:5432/geoq_dev" --username=postgres --password=4652 diffChangeLog --referenceUrl="jdbc:postgresql://localhost:5432/geoq_dev_full" --referenceUsername=postgres --referencePassword=4652

四、對現有數據庫進行重構

數據庫變更日志文件可以對數據庫的變更進行版本管理,並且可以擺脫對特定數據庫的依賴,因此需要了解數據庫變更日志文件的相關語法,下面分別介紹如何通過數據庫變更日志配置數據庫重構。

1、編輯列:

添加列

    <changeSet id="4" author="joe">
        <addColumn tableName="distributor">
          <column name="phonenumber" type="varchar(255)"/>
        </addColumn>
    </changeSet>

添加自增列:

    <column autoIncrement="true" name="module_config_id" type="int" startWith="1">
        <constraints nullable="false" primaryKey="true" primaryKeyName="pk_t_module_config"/>
    </column>

刪除列:

    <dropColumn tableName="distributor" columnName="phonenumber"/>

修改已存在的列為自增列

    <addAutoIncrement tableName="person" columnName="id" columnDataType="int"/>

修改postgresql自增列當前索引值:liquibase不支持該操作,可以使用sql標簽實現

    <sql>
        ALTER SEQUENCE t_role_role_id_seq RESTART WITH 3;
    </sql>

2、創建表:

    <changeSet id="3" author="betsey">
        <createTable tableName="distributor">
          <column name="id" type="int">
            <constraints primaryKey="true" nullable="false"/>
          </column>
          <column name="name" type="varchar(255)">
            <constraints nullable="false"/>
          </column>
          <column name="address" type="varchar(255)">
            <constraints nullable="true"/>
          </column>
          <column name="active" type="boolean" defaultValue="1"/>
        </createTable>
    </changeSet>

3、操作數據:

    <changeSet id="3" author="betsey">
        <code type="section" width="100%">
        <insert tableName="distributor">
          <column name="id" valueNumeric="3"/>
          <column name="name" value="Manassas Beer Company"/>
        </insert>
        <insert tableName="distributor">
          <column name="id" valueNumeric="4"/>
          <column name="name" value="Harrisonburg Beer Distributors"/>
        </insert>
    </changeSet>

應該編寫用於操作數據的 SQL 腳本,因為使用 LiquiBase XML 變更集限制很多。有時候使用 SQL 腳本向數據庫應用大量的變更會簡單一些。LiquiBase 也可以支持這些情景。

如下例為從 LiquiBase 變更集運行一個定制 SQL 文件

    <changeSet id="6" author="joe"> 
        <sqlFile path="insert-distributor-data.sql"/>
    </changeSet>

編寫changeset時,如果字段的內容為html標簽,可以使用<![CDATA[html tag]]符號導入帶有html標簽的文本。 

4、操作序列:

創建序列

<createSequence sequenceName="seq_employee_id"/>

sequenceName

序列名稱 [required]

schemaName

schema名稱

incrementBy

自增間隔值

minValue

序列的最小值

maxValue

序列的最大值

ordered

'true' 或者 'false'

startValue

序列的起始值

修改序列

<alterSequence sequenceName="seq_employee_id" incrementBy="10"/>

sequenceName

序列的名稱 [required]

incrementBy

新的自增間隔值 [required]

 五、liquibase-maven-plugin基本命令

  • 更新數據庫:mvn liquibase:update
  • 打版本標簽:mvn liquibase:tag
  • 回滾到最近的更新版本,或指定的標簽版本,或日期,或更新次數:mvn liquibase:rollback -Dliquibase.rollbackCount=1
  • 生成sql更新腳本:mvn liquibase:updateSQL

 六、數據庫版本控制

1、添加版本標簽:

a、使用命令行:

mvn liquibase:tag -Dliquibase.tag=checkpoint

b、使用配置文件:

    <executions>
        <execution>
            <phase>process-resources</phase>
            <configuration>
                <tag>${project.version}</tag>
            </configuration>
            <goals>
                <goal>update</goal>
                <goal>tag</goal>
            </goals>
        </execution>
    </executions>

2、可以使用如下命令回滾到某個版本:

    mvn liquibase:rollback -Dliquibase.rollbackTag=checkpoint

對應的maven配置為:

    <executions>
        <execution>
            <phase>process-resources</phase>
            <configuration>
                <changeLogFile>src/main/resources/liquiabse/master-changelog.xml</changeLogFile>
                <driver>${jdbc.driverClassName}</driver>
                <url>${jdbc.url}</url>
                <username>${jdbc.username}</username>
                <password>${jdbc.password}</password>
                <rollbackTag>1.1</rollbackTag>
            </configuration>
            <goals>
                <goal>update</goal>
                <goal>rollback</goal>
            </goals>
        </execution>
    </executions>

rollback操作可選參數包括:

changeLogFile

String

設置Liquibase變更集文件

clearCheckSums

boolean

標識是否強制清除數據庫表校驗.

默認值為:false.

contexts

String

配置Liquibase執行的上下文,多個上下文可以使用逗號分隔

databaseClass

String

數據庫對象的類

defaultSchemaName

String

數據庫連接使用的默認數據庫結構名稱

driver

String

數據庫連接的驅動名稱

emptyPassword

boolean

已過期。是否使用空字符串或null作為數據庫連接密碼

默認值為:false.

expressionVariables

Map

傳遞給插件的數組變量

expressionVars

Properties

傳遞給插件的數組變量

includeArtifact

boolean

是否允許為獲取Liquibase屬性或數據庫變更日志時包含maven項目組件

默認值為:true.

includeTestOutputDirectory

boolean

是否允許為獲取Liquibase屬性或數據庫變更日志時包含測試輸出目錄

默認值為:true.

logging

String

控制插件輸出的日志級別。 可選值包括:"all", "finest", "finer", "fine", "info", "warning", "severe" or "off",注意該值是區分大小寫的。

默認值為:INFO.

password

String

數據庫連接密碼

promptOnNonLocalDatabase

boolean

是否允許控制用戶執行遠程數據庫
默認值為:true.

propertyFile

String

Liquibase屬性文件位置

propertyFileWillOverride

boolean

標志是否允許使用Liquibase屬性文件覆蓋插件的配置

默認值為:false.

rollbackCount

int

回滾的變更集個數

默認值為:-1.

rollbackDate

String

設置回滾的日期。日期格式要符合插件執行theDateFormat.getDateInstance()操作設置的日期格式

rollbackTag

String

要回滾到那個tag

server

String

在settings.xml中的服務器id進行身份驗證時使用

skip

boolean

設置為“true”跳過運行liquibase,該參數不推薦使用

systemProperties

Properties

傳遞到數據庫的系統屬性

url

String

數據庫連接地址

username

String

用戶名稱

verbose

boolean

控制調用插件的輸出的詳細程度。

默認值為:false.


也可以指定回滾的步數(
changeset個數):

    mvn liquibase:rollback -Dliquibase.rollbackCount=3

或者生成回滾的sql腳本:

    mvn liquibase:rollbackSQL -Dliquibase.rollbackTag=checkpoint

3、可以根據不同的版本分別創建相關changelog文件,使用include標簽分別引入,如主干changelog文件為master-changelog.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"
      xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd">
        <include file="src/main/resources/liquibase/liquibase-create-tables.xml" />
        <include file="src/main/resources/liquibase/liquibase-insert-data.xml" />
        <include file="src/main/resources/liquibase/liquibase-mobile-menu.xml" />
        …...
        <include file="src/main/resources/liquibase/liquibase-update-to-1.4.xml"/>
        <include file="src/main/resources/liquibase/liquibase-update-to-1.6.xml"/>
        …...
    </databaseChangeLog>

七、創建特殊的類型的字段

changelog文件中,如希望創建postgresql支持的enum,可以使用的方法如下:

1、使用sql腳本直接創建

    <changeSet id="1" author="Arthur">
        <sql>CREATE TYPE my_state AS ENUM ('yes','no')</sql>
        <table name="foo">
            <column name="state" type="my_state"/>
        </table>
    </changeSet>

2、使用約束

    <changeSet id="1" author="X">
        <table name="t">
            <column name="c" type="varchar(3)"/>
        </table>
        <sql>ALTER TABLE t ADD CONSTRAINT check_yes_no CHECK (c = 'yes' OR c = 'no')</sql>
    </changeSet>

3、獲取系統當前時間

首先定義不同數據庫獲取時間的屬性標簽

    <property name="now" value="sysdate" dbms="oracle"/>
    <property name="now" value="now()" dbms="mysql"/>

changesets中引用該屬性

    <column name="Join_date" defaultValueFunction="${now}"/>

完整示例如下:

    <property name="now" value="UNIX_TIMESTAMP()" dbms="mysql"/>
    <changeSet id="emp_1" author="Me">
        <insert tableName="Emp" schemaName="XYZ">
            <column name="EmpName" value="abc"/>
            <column name="Join_date" valueDate="${now}"/>
            <column name="Profile_last_update" valueDate="${now}"/>
            <column name="group_name" value="BlahBlah"/>
        </insert>
    </changeset>

八、支持多數據庫

可以在pom文件使用多個execution標簽支持多數據庫,但是需要注意每個execution一定要定義id標簽

    <plugin>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-plugin</artifactId>
        <version>1.9.5.0</version>
        <executions>
            <execution>
                <phase>process-resources</phase>
                <configuration>
                    <changeLogFile>src/main/resources/db.changelog.xml</changeLogFile>
                    <driver>com.mysql.jdbc.Driver</driver>
                    <url>jdbc:mysql://localhost:3306/charm</url>  
                    <username>***</username>
                    <password>***</password>
                </configuration>
                <goals>
                    <goal>update</goal>
                </goals>
            </execution>
            <execution>
                <phase>process-resources</phase>
                <configuration>
                    <changeLogFile>src/main/resources/db.changelog.xml</changeLogFile>
                    <driver>com.mysql.jdbc.Driver</driver>
                    <url>jdbc:mysql://localhost:3306/charm2</url>  
                    <username>***</username>
                    <password>***</password>
                </configuration>
                <goals>
                    <goal>update</goal>
                </goals>
            </execution>
        </executions>
    </plugin>

九、參考網站

主站:http://www.liquibase.org/

幫助手冊:http://www.liquibase.org/manual/home

properties-maven-plugin手冊:http://www.liquibase.org/manual/maven


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM