最近项目一度因为特殊原因导致频繁迁移数据库,中间也出了不少事故。原先项目上只在数据库初始化的时候使用了Liquibase,为了便于日后数据的管理,不再出可避免的差错,决定开发过程中也使用Liquibase。
Liquibase是一个用于数据库重构和迁移的开源工具,通过日志文件的形式记录数据库的变更,然后执行日志文件中的修改,将数据库更新或回滚到一致的状态。Liquibase的主要特点有:
- 支持几乎所有主流的数据库,如MySQL, PostgreSQL, Oracle, Sql Server, DB2等;
- 支持多开发者的协作维护;
- 日志文件支持多种格式,如XML, YAML, JSON, SQL等;
- 支持多种运行方式,如命令行、Spring集成、Maven插件、Gradle插件等;
本文首先简单介绍一下Liquibase的changelog文件格式,然后介绍在Maven中集成并运行Liquibase。
对于Liquibase的相关标签就不介绍了,如果有需要,可以参考:http://www.liquibase.org/documentation/index.html。
databaseChangeLog文件格式
XML格式
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.1.xsd
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.0.xsd
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-2.0.xsd
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.9.xsd
http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-1.8.xsd
<?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-3.0.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<preConditions>
<runningAs username="liquibase"/>
</preConditions>
<changeSet id="1" author="zoe">
<createTable tableName="person">
<column name="id" type="int" autoIncrement="true">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="firstname" type="varchar(50)"/>
<column name="lastname" type="varchar(50)">
<constraints nullable="false"/>
</column>
<column name="state" type="char(2)"/>
</createTable>
</changeSet>
</databaseChangeLog>
YAML格式
当使用YAML格式时需要导入snakeyaml-1.12.jar(liquibase3.4.2在lib包下自带有)用于支持格式解析。
databaseChangeLog:
- preConditions:
- runningAs:
username: liquibase
- changeSet:
id: 1
author: zoe
changes:
- createTable:
tableName: person
columns:
- column:
name: id
type: int
autoIncrement: true
constraints:
primaryKey: true
nullable: false
- column:
name: firstname
type: varchar(50)
- column:
name: lastname
type: varchar(50)
constraints:
nullable: false
- column:
name: state
type: char(2)
JSON格式
{
"databaseChangeLog": [
{
"preConditions": [
{
"runningAs": {
"username": "liquibase"
}
}
]
},
{
"changeSet": {
"id": "1",
"author": "zoe",
"changes": [
{
"createTable": {
"tableName": "person",
"columns": [
{
"column": {
"name": "id",
"type": "int",
"autoIncrement": true,
"constraints": {
"primaryKey": true,
"nullable": false
},
}
},
{
"column": {
"name": "firstname",
"type": "varchar(50)"
}
},
{
"column": {
"name": "lastname",
"type": "varchar(50)",
"constraints": {
"nullable": false
},
}
},
{
"column": {
"name": "state",
"type": "char(2)"
}
}
]
}
}
]
}
}
]
}
SQL格式
Liquibase2.0版本之后changelog文件支持sql格式。
SQL格式的文件使用sql注解来配置元数据信息。一个changelog文件标记:
--liquibase formatted sql
在文件中添加变化集:
--changeset author:id attribute1:value1 attribute2:value2 [...]
在sql格式文件中的changeSet也支持设置Preconditions:
--preconditions onFail:HALT onError:HALT
当前只支持sql检查:
--precondition-sql-check expectedResult:0 SELECT COUNT(*) FROM my_table
在sql格式文件中的changeSet也支持设置Rollback Actions:
--rollback SQL STATEMENT
示例:
--liquibase formatted sql
--changeset zoe:1
create table test1 (
id int primary key,
name varchar(255)
);
--rollback drop table test1;
--changeset nvoxland:2
insert into test1 (id, name) values (1, ‘name 1′);
insert into test1 (id, name) values (2, ‘name 2′);
--changeset nvoxland:3 dbms:oracle
create sequence seq_test;
Maven集成Liquibase
liquibase-maven-plugin插件
Maven中集成LiquiBase,主要是配置liquibase-maven-plugin,在pom.xml中添加此插件
<plugins>
<plugin>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-maven-plugin</artifactId>
<version>3.4.2</version>
<configuration>
<!--skip为true时表示跳不执行-->
<skip>${skipLiquibaseRun}</skip>
</configuration>
<dependencies>
<dependency>
<groupId>com.oracle</groupId>
<artifactId>ojdbc7</artifactId>
<version>12.1.0.1.0</version>
</dependency>
<dependency>
<groupId>com.microsoft.sqlserver</groupId>
<artifactId>sqljdbc4</artifactId>
<version>4.2</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.34</version>
</dependency>
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-groovy-dsl</artifactId>
<version>1.2.1</version>
</dependency>
<dependency>
<groupId>org.codehaus.groovy</groupId>
<artifactId>groovy-xml</artifactId>
<version>2.4.6</version>
</dependency>
</dependencies>
<executions>
<execution>
<id>clearCheckSums</id>
<!--配置什么时候执行数据库变更日志中的SQL脚本-->
<phase>process-resources</phase>
<configuration>
<driver>${db.driver}</driver>
<url>${db.url}</url>
<username>${db.user}</username>
<password>${db.password}</password>
<promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
</configuration>
<goals>
<goal>clearCheckSums</goal>
</goals>
</execution>
<execution>
<id>update</id>
<phase>process-resources</phase>
<configuration>
<!--数数据库变更日志文件-->
<changeLogFile>${db.file}</changeLogFile>
<driver>${db.driver}</driver>
<url>${db.url}</url>
<username>${db.user}</username>
<password>${db.password}</password>
<promptOnNonLocalDatabase>false</promptOnNonLocalDatabase>
</configuration>
<goals>
<goal>update</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
其中< configuration>节点中的配置可以放在单独的配置文件里。
编写changelog文件
准备好之后,就是编辑数据库变更日志了,这里以sql格式为例。
在fish/core/db路径下编写changeLog.sql日志文件
--changeset zoe:1
create table test1 (
id int primary key,
name varchar(255)
);
--rollback drop table test1;
--changeset zoe:2
insert into test1 (id, name) values (1, "name 1");
insert into test1 (id, name) values (2, "name 2");
执行mvn命令
mvn process-resources -D skipLiquibaseRun=false -D db.driver=com.mysql.jdbc.Driver -D db.url=jdbc:mysql://xx.xx.xx.xx:3306/test -D db.user=user -D db.password=pwd -D db.file=fish/core/db/changeLog.sql
skipLiquibaseRun=false对应< skip>配置的
driver指定jdbc驱动类
classpath指定驱动包路径
changeLogFile指定变更文件
url指定数据库链接url
username指定数据库账号
password指定数据库密码
如果执行报错找不到fish/core/db/changeLog.sql文件【 File does not exist: fish/core/db/changeLog.sql】

到target对应目录下去看,发现确实没有,这就是因为可能配置了资源过滤,在pom.xml中把.sql文件加上就行了:

然后重新执行成功后,查看数据库,已经建表成功,并插入了正确数据。

继续验证,在changeLog.sql中加入
--changeset zoe:3
insert into test1 (id, name) values (3, "name 3");
然后再次执行刚刚的mvn命令,日志中很清晰看到这次只执行了新加的changeset

成功后验证数据库

这样在后续的开发过程中,所有涉及表结构变更的都通过changeset记录下来,迁移数据库的时候只需要执行一下changgelog文件就可以了。
本文详细介绍了如何使用LiquiBase进行数据库迁移,包括其支持的databaseChangeLog文件格式(XML, YAML, JSON, SQL)以及在Maven项目中集成Liquibase的步骤,强调了在Maven配置中添加sql格式文件的注意事项,通过实例展示了如何编写和执行变更日志文件,以确保数据库的一致性。"
2204315,261214,光盘物理结构与信息记录原理解析,"['存储技术', '光学存储', '数据编码', '制造过程', '光盘原理']
5321

被折叠的 条评论
为什么被折叠?



