





















数据库版本管理、持续集成一直都是大家比较关心的问题,网上也有很多相关的文章介绍。一直都很羡慕ruby on rails的database 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数据库变更日志文件
4、driver、url、username、password配置数据库连接参数
三、根据数据库生成数据库变更日志文件
针对已有的数据库,如何产生对应的数据库变更日志文件,可以使用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,该参数包括如下可选项:
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基本命令
六、数据库版本控制
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/manual/home
properties-maven-plugin手册:http://www.liquibase.org/manual/maven
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。