zoukankan      html  css  js  c++  java
  • 使用liquibasemavenplugin实现持续数据库集成

    数据库版本管理、持续集成一直都是大家比较关心的问题,网上也有很多相关的文章介绍。一直都很羡慕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

  • 相关阅读:
    Android(java)学习笔记92:Android线程形态之 AsyncTask (异步任务)
    Android(java)学习笔记91:Eclipse中代码提示去掉@override,不然就报错!
    Android(java)学习笔记90:TextView 添加超链接(两种实现方式)
    Android(java)学习笔记89:Bundle和Intent类使用和交互
    Android(java)学习笔记88:BaseAdapter适配器重写之getView()
    PHP笔记08:数据库编程---使用php的MySQL扩展库操作MySQL数据库
    Android(java)学习笔记87:Android音视频MediaRecorder用法
    Android(java)学习笔记86:Android提供打开各种文件的API接口:setDataAndType
    HDU 5480 Conturbatio
    HDU 5479 Scaena Felix
  • 原文地址:https://www.cnblogs.com/gao241/p/2971526.html
Copyright © 2011-2022 走看看