LiquiBase是一个用于数据库重构和迁移的开源工具,经过日志文件的形式记录数据库的变动,而后执行日志文件中的修改,将数据库更新或回滚到一致的状态。html
LiquiBase的主要特色有:java
本文首先简单介绍一下LiquiBase的changelog文件的经常使用标签配置,而后介绍在Maven中集成并运行LiquiBase。mysql
changelog是LiquiBase用来记录数据库的变动,通常放在CLASSPATH
下,而后配置到执行路径中。sql
changelog支持多种格式,主要有XML/JSON/YAML/SQL,其中XML/JSON/YAML除了具体格式语法不一样,节点配置很相似,SQL格式中主要记录SQL语句,这里仅给出XML格式和SQL格式的示例,更多的格式示例请参考文档
数据库
changelog.xmlmaven
<changeSet id="2" author="daniel" runOnChange="true"> <insert tableName="contest_info"> <column name="id">3</column> <column name="title">title 3</column> <column name="content">content 3</column> </insert> </changeSet>
changelog.sqlide
--liquibase formatted sql --changeset daniel:16040707 CREATE TABLE `role_authority_sum` ( `row_id` int(11) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增id', `role_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '关联role的role_id', `authority_sum` int(11) unsigned NOT NULL DEFAULT '0' COMMENT 'perms的值的和', `data_type_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '关联data_type的id', PRIMARY KEY (`row_id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='角色的权限值的和,如角色有RD权限,则和为2+8=10';
一个<changeSet>标签对应一个变动集,由id、name、以及changelog的文件路径组成惟一标识。changelog在执行的时候并非按照id的顺序,而是按照changeSet在changelog中出现的顺序。函数
LiquiBase在执行changelog时,会在数据库中插入两张表:DATABASECHANGELOG
和DATABASECHANGELOGLOCK
,分别记录changelog的执行日志和锁日志。工具
LiquiBase在执行changelog中的changeSet时,会首先查看DATABASECHANGELOG
表,若是已经执行过,则会跳过(除非changeSet的runAlways
属性为true,后面会介绍),若是没有执行过,则执行并记录changelog日志;ui
changelog中的一个changeSet对应一个事务,在changeSet执行完后commit,若是出现错误则rollback;
<changeSet>
标签的主要属性有:
DATABASECHANGELOG
表中还记录了changeSet的MD5校验值MD5SUM,若是changeSet的id
和name
没变,而内容变了,则因为MD5值变了,即便runAlways的值为True,执行也是失败的,会报错。这种状况应该使用runOnChange
属性。<changeSet>
下有一个重要的子标签<rollback>
,即定义回滚的SQL语句。对于create table
, rename column
和add column
等,LiquiBase会自动生成对应的rollback语句,而对于drop table
、insert data
等则须要显示定义rollback语句。
<include>
与<includeAll>
标签当changelog文件愈来愈多时,可使用<include>
将文件管理起来,如:
<?xml version="1.0" encoding="utf-8"?> <databaseChangeLog xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.liquibase.org/xml/ns/dbchangelog" xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd"> <include file="logset-20160408/0001_authorization_init.sql" relativeToChangelogFile="true"/> </databaseChangeLog>
<include>
的file属性表示要包含的changelog文件的路径,这个文件能够是LiquiBase支持的任意格式,relativeToChangelogFile若是为true,则表示file属性表示的文件路径是相对于根changelog而不是CLASSPATH的,默认为false。
<includeAll>
指定的是changelog的目录,而不是为文件,如:
<includeAll path="com/example/changelogs/"/>
注意: 目前<include>
没有解决重复引用和循环引用的问题,重复引用还好,LiquiBase在执行的时候能够判断重复,而循环引用会致使无限循环,须要注意!
diff命令用于比较数据库之间的异同。好比经过命令行执行:
java -jar liquibase.jar --driver=com.mysql.jdbc.Driver \
--classpath=./mysql-connector-java-5.1.29.jar \
--url=jdbc:mysql://127.0.0.1:3306/test \
--username=root --password=passwd \
diff \
--referenceUrl=jdbc:mysql://127.0.0.1:3306/authorization \
--referenceUsername=root --referencePassword=passwd
在已有的项目上使用LiquiBase,要生成当前数据库的changeset,能够采用两种方式,一种是使用数据库工具导出SQL数据,而后changelog文件以SQL格式记录便可;另外一种方式就是用generateChangeLog
命令,如:
liquibase --driver=com.mysql.jdbc.Driver \
--classpath=./mysql-connector-java-5.1.29.jar \
--changeLogFile=liquibase/db.changelog.xml \
--url="jdbc:mysql://127.0.0.1:3306/test" \
--username=root \
--password=yourpass \
generateChangeLog
不过generateChangeLog
不支持如下功能:存储过程、函数以及触发器;
liquibase-maven-plugin
的配置Maven中集成LiquiBase,主要是配置liquibase-maven-plugin
,首先给出一个示例:
<plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>3.4.2</version> <configuration> <changeLogFile>src/main/resources/liquibase/test_changelog.xml</changeLogFile> <driver>com.mysql.jdbc.Driver</driver> <url>jdbc:mysql://127.0.0.1:3306/test</url> <username>root</username> <password>passwd</password> </configuration> <executions> <execution> <phase>process-resources</phase> <goals> <goal>update</goal> </goals> </execution> </executions> </plugin>
其中<configuration>
节点中的配置能够放在单独的配置文件里。
若是须要在父项目中配置子项目共享的LiquiBase配置,而各个子项目能够定义本身的配置,并覆盖父项目中的配置,则只须要在父项目的pom中将propertyFileWillOverride
设置为true便可,如:
<plugin> <groupId>org.liquibase</groupId> <artifactId>liquibase-maven-plugin</artifactId> <version>3.4.2</version> <configuration> <propertyFileWillOverride>true</propertyFileWillOverride> <propertyFile>liquibase/liquibase.properties</propertyFile> </configuration> </plugin>
liquibase:update
执行changelog中的变动:
$ mvn liquibase:update
liquibase:rollback
rollback有3中形式,分别是:
- rollbackCount: 表示rollback的changeset的个数; - rollbackDate:表示rollback到指定的日期; - rollbackTag:表示rollback到指定的tag,须要使用LiquiBase在具体的时间点打上tag;
rollbackCount
比较简单,示例如:
$ mvn liquibase:rollback -Dliquibase.rollbackCount=3
rollbackDate
须要注意日期的格式,必须匹配当前平台上执行DateFormat.getDateInstance()
获得的格式,好比个人格式为MMM d, yyyy
,示例如:
$ mvn liquibase:rollback -Dliquibase.rollbackDate="Apr 10, 2016"
rollbackTag
使用tag标识,因此须要先打tag,示例如:
$ mvn liquibase:tag -Dliquibase.tag=tag20160410
而后rollback到tag20160410,如:
$ mvn liquibase:rollback -Dliquibase.rollbackTag=tag20160410