惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

V
V2EX
J
Java Code Geeks
MongoDB | Blog
MongoDB | Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
Engineering at Meta
Engineering at Meta
美团技术团队
N
Netflix TechBlog - Medium
月光博客
月光博客
博客园 - 三生石上(FineUI控件)
F
Fortinet All Blogs
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
MyScale Blog
MyScale Blog
aimingoo的专栏
aimingoo的专栏
Last Week in AI
Last Week in AI
The Cloudflare Blog
量子位
Apple Machine Learning Research
Apple Machine Learning Research
小众软件
小众软件
腾讯CDC
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
D
DataBreaches.Net
H
Hackread – Cybersecurity News, Data Breaches, AI and More

博客园 - 没头脑的土豆

(转)Python实例手册 (转)shell实例手册 Jetty嵌入式Web容器攻略 H2数据库攻略 CAS ticket过期策略 CAS自定义登录验证方法 Sonatype Nexus高级配置 配置sonar、jenkins进行持续审查 Scrum敏捷精要 使用yuicompressor-maven-plugin压缩js及css文件 (转)Rails Web应用相关插件和资源列表 (转)了解Instagram背后的技术 Jenkins服务器安装与配置 Jenkins配置基于角色的项目权限管理 Android-x86虚拟机安装配置全攻略 CenOS系统中安装Tomcat7并设置为自启动服务 CentOS系统中安装JDK1.6 CentOS系统中安装Nexus并导入已有的构件库 (转)Esri微博地址收录
使用liquibase-maven-plugin实现持续数据库集成
没头脑的土豆 · 2013-03-20 · via 博客园 - 没头脑的土豆

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


也可以指定回滚的步数(
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