简介
LiquiBase是一个用于数据库重构和迁移的开源工具,通过日志文件的形式记录数据库的变更,然后执行日志文件中的修改,将数据库更新或回滚到一致的状态。
LiquiBase的主要特点有:
支持几乎所有主流的数据库,如MySQL, PostgreSQL, Oracle, Sql Server, DB2等;
支持多开发者的协作维护;
日志文件支持多种格式,如XML, YAML, JSON, SQL等;
支持多种运行方式,如命令行、Spring集成、Maven插件、Gradle插件等;
changelog文件格式
changelog是LiquiBase用来记录数据库的变更,一般放在CLASSPATH下,然后配置到执行路径中。
changelog支持多种格式,主要有XML/JSON/YAML/SQL,其中XML/JSON/YAML除了具体格式语法不同,节点配置很类似,SQL格式中主要记录SQL语句,后面实例有给出XML格式和SQL格式的示例,更多的格式示例请参考http://www.liquibase.org/
常用的标签及命令
1. 标签
一个<changeSet>标签对应一个变更集,由属性id、name,以及changelog的文件路径唯一标识。changelog在执行的时候并不是按照id的顺序,而是按照changeSet在changelog中出现的顺序。
changelog中的一个changeSet对应一个事务,在changeSet执行完后commit,如果出现错误则rollback。
2. <include>与<includeAll>标签
<include>的file属性表示要包含的changelog文件的路径,这个文件可以是LiquiBase支持的任意格式,relativeToChangelogFile如果为true,则表示file属性表示的文件路径是相对于根changelog而不是CLASSPATH的,默认为false。
<includeAll>指定的是changelog的目录,而不是为文件,如:
<includeAll path="com/example/changelogs/"/>
注意: 目前<include>没有解决重复引用和循环引用的问题,重复引用还好,LiquiBase在执行的时候可以判断重复,而循环引用会导致无限循环,需要注意!
实例
pom.xml
<dependency>
<groupId>org.liquibase</groupId>
<artifactId>liquibase-core</artifactId>
</dependency>
application.yml
spring:
profiles:
active: dev
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://${MYSQL_HOST:localhost}:3306/liquibase?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf-8&useSSL=false
username: root
password: 123456
liquibase:
change-log: classpath:liquibase/changelog-master.xml
contexts: ${spring.profiles.active}
enabled: true # 是否启用,默认为true,开发环境可以改成false,手动执行
changelog-master.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"
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.1.xsd
http://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsd">
<includeAll path="liquibase/changelogs"/>
</databaseChangeLog>
changelog-1.0.0.xml
changelog-1.1.0.sql
-- liquibase formatted sql
-- changeset lenky.li:department-createTable-20181205
CREATE TABLE `department` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(60) DEFAULT NULL COMMENT '部门名称',
`create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间',
`update_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci COMMENT='部门';
-- changeset lenky.li:department-modify-20181205
ALTER TABLE `liquibase`.`department`
ADD COLUMN `create_by` varchar(32) NULL COMMENT '创建人' AFTER `update_time`;
-- changeset lenky.li:department-init-20181205
INSERT INTO `liquibase`.`department`(`id`, `name`, `create_time`, `update_time`, `create_by`) VALUES (1, '技术部', '2021-02-10 09:56:59', '2021-02-10 09:56:59', 'admin');
执行记录
在执行changelog的时候,会在数据库记录执行记录,主要用了下面的两张表:
databasechangelog
databasechangeloglock
拓展
前置条件:可以放整个changelog前面,也可以放在changeset里面
上下文:测试环境初始化测试数据,生产不执行
参数:自定义变量
回滚
http://www.liquibase.org/documentation/rollback.html
https://github.com/icyxp/liquibase-demo
总结
1、语法简单,开箱即用
2、功能强大,满足日常数据库脚本变更需求
3、版本管理方便,每次修改都有记录
4、与项目集成,项目启动执行数据库变更,发布省去手动初始化脚本
最佳实践:推荐使用SQL脚本的方式,开发阶段改动比较频繁,开发可以不启用,把变更集维护好,一个变更集的维度可以自由发挥,可以按天,也可以按开发周期。test、uat、prod则启动,自动执行。