What’s Liquibase?

Liquibase是一个用于跟踪、管理和应用数据库变化的开源的数据库重构工具。它将所有数据库的变化(包括结构和数据)都保存在XML文件中,便于版本控制。

Liquibase具备如下特性:

* 不依赖于特定的数据库,目前支持包括Oracle/Sql Server/DB2/MySql/Sybase/PostgreSQL/Caché等12种数据库,这样在数据库的部署和升级环节可帮助应用系统支持多数据库。
* 提供数据库比较功能,比较结果保存在XML中,基于该XML你可用Liquibase轻松部署或升级数据库。
* 以XML存储数据库变化,其中以作者和ID唯一标识一个变化(ChangSet),支持数据库变化的合并,因此支持多开发人员同时工作。
* 在数据库中保存数据库修改历史(DatabaseChangeHistory),在数据库升级时自动跳过已应用的变化(ChangSet)。
* 提供变化应用的回滚功能,可按时间、数量或标签(tag)回滚已应用的变化。通过这种方式,开发人员可轻易的还原数据库在任何时间点的状态。
* 可生成数据库修改文档(HTML格式)
* 提供数据重构的独立的IDE和Eclipse插件

 

Integrate Liquibase with Ant

你所需要的Liquibase环境,其实只是一个Jar包而已。 通过Ant加载该Jar包,就可以集成Liquibase实现数据版本控制

Liquibasse支持原生SQL,但是推荐使用Liquibase的Changeset语法,因为ChangeSet语法是跨数据库的,你几乎不会有数据库迁移的麻烦,这也是Liquibase受到追捧的原因之一。

怎么构建一个HelloWorld表

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

<changeSet id="1.0.0" author="ryan" >
  <createTable tableName="helloworld">
   <column name="ID" type="VARCHAR2(40)">
    <constraints primaryKey="true" nullable="false"/>
   </column>
   <column name="KEY" type="VARCHAR2(200)"/>           
   <column name="DISPLAYNAME" type="VARCHAR2(200)" />
   <column name="DEFAULT_MESSAGE" type="CLOB" />
  </createTable>
  <rollback>
    drop table helloworld;
  </rollback>
 </changeSet>
</databaseChangeLog>

上面的XML 文件定义了创建Helloworld表的语句,同时ChangeSetID为1.0.0 。 这个ID是相当重要,ID会作为Version控制的唯一标识,如果你要回滚操作,就可以根据相应的ID进行回滚。

引入Liquibase Jar包

    <path id="classpath-liquibase">
        <fileset dir="${global.dir}/../lib/">
            <include name="liquibase.jar" />
            <include name="ojdbc14.jar" />
        </fileset>
    </path>

更新数据表:

        <ant target="update-Database-handler">
            <property name="update.changeSet.file" value="${changeSet.file}" />
            <property name="update-database-schema" value="schemaA" />
            <property name="database.username" value="${jdbc.user}" />
            <property name="database.password" value="${jdbc.password}" />
            <property name="databaseChangeLogTableName" value="${databaseChangeLogTableName}" />
            <property name="databaseChangeLogLockTableName" value="${databaseChangeLogLockTableName}" />
        </ant>

此段ANT语句定义了Update操作,你需要通过Propertis传入相应的ChangeSet文件路径以及数据库相应的用户名密码。

databaseChangelogTablename 代表日志表,
databaseChangeLogLockTableName代表锁状态表。

Tag Table :

<ant target="tag-handler">
            <property name="database.username" value="${jdbc.user}" />
            <property name="database.password" value="${jdbc.password}" />
            <property name="tag.id" value="${tag.id}" />
            <property name="databaseChangeLogTableName" value="${databaseChangeLogTableName}" />
            <property name="databaseChangeLogLockTableName" value="${databaseChangeLogLockTableName}" />
        </ant>

当你更新了多个ChangeSet文件并测试稳定过后,你需要将当前的变更打上一个Tag,也就是一个新的版本,而这个Tag Id 最好与最新的ChangeSet ID 保持一致,一定要注意,Liquibase只支持基于TagID的回滚,所以当版本稳定过后一定要打上Tag。

Rollback Database:

  <target name="rollback-Database-handler">
        <echo message="Roll Back Database incording the file of ${rollback.changeSet.file}" />
        <echo>url="${jdbc.url}"</echo>
        <echo>username="${database.username}"</echo>
        <echo>password="${database.password}"</echo>
        <echo>rollbackTag="${rollback.tag.id}"</echo>
        <taskdef resource="liquibasetasks.properties">
            <classpath refid="classpath-liquibase" />
        </taskdef>
        <if name="liquibase.mode" value="output">
            <property name="outputProperties" value="${sql.file.output.dir}/${rollback-database-schema}.${outputSql.suffix}" />
            <rollbackDatabase changeLogFile="${rollback.changeSet.file}" url="${jdbc.url}" username="${database.username}" password="${database.password}" classpathref="classpath-liquibase" rollbackTag="${rollback.tag.id}" databaseChangeLogTableName="${databaseChangeLogTableName}" databaseChangeLogLockTableName="${databaseChangeLogLockTableName}" outputFile="${outputProperties}">
            </rollbackDatabase>
            <else>
                <rollbackDatabase changeLogFile="${rollback.changeSet.file}" url="${jdbc.url}" username="${database.username}" password="${database.password}" classpathref="classpath-liquibase" rollbackTag="${rollback.tag.id}" databaseChangeLogTableName="${databaseChangeLogTableName}" databaseChangeLogLockTableName="${databaseChangeLogLockTableName}">
                </rollbackDatabase>
            </else>
        </if>
    </target>

上面的代码就是基于TagId的回滚。Liquibase对于Update和Roll Back操作支持Output模式,也就是不会对数据库进行操作,只是将ChangeSet的语法转义为相应的SQL语句并输出,这样的话你可以在本地更方便的进行分离测试。

Leave a Reply

Your email address will not be published. Required fields are marked *

%d bloggers like this: