Liquibase学习并使用

Liquibase是一个用于数据库重构和迁移的工具,适用于多开发人员协作的场景,支持MySQL等多种数据库。它通过changelog文件记录数据库变更,提供回滚功能。本文介绍了Liquibase的主要特点、changelog的XML和SQL格式、开始使用Liquibase的步骤,以及在Spring Boot中集成和测试的案例。此外,还强调了使用过程中的注意事项,包括文件命名规范和执行顺序问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1、关于Liquibase

适用场景

开发过程经常会有表结构和变更,让运维来维护的话,通常会有很大的沟通成本,有时在开发方案有问题的时候,提测失败整个项目需要回滚,代码回滚起来是很容易的,通常有备份,但数据库的话就要人工来逐行分析并写出回滚语句,Liquibase 这时候就有用了。

Liquibase是用于数据库重构和迁移的数据工具,通过日志文件的形式记录数据库的变更,然后执行日志文件中的数据库修改,将数据库更新或回滚到一致的状态,主要用于项目中上线初始化数据库,后续程序数据库升级与回退迁移,更加方便开发者高效、安全的进行数据库升级与回滚

liquibase主要特点

  • 支持几乎所有主流的数据库,如MySQL, PostgreSQL, Oracle, Sql Server, DB2等;
  • 提供数据库比较功能,比较结果保存在XML中,基于该XML你可用Liquibase轻松部署或升级数据库。
  • 以XML存储数据库变化,其中以作者和ID唯一标识一个变化(changset),支持数据库变化的合并,因此支持多开发人员同时合作。
  • 提供变化应用的回滚功能,可按时间,数量或标签(tag)回滚已应用的变化。通过这种方式,开发人员可轻易的还原数据库在任何时间点的状态
  • 日志文件支持多种格式,如xml、yaml、json、sql等(sql格式2.0以后支持);
  • 支持多种运行方式,如命令行、Spring集成、Maven插件、Gradle插件等;

changelog文件格式

changelog是LiquiBase用来记录数据库的变更,一般放在CLASSPATH下,然后配置到执行路径中。

changelog支持多种格式,主要有XML/JSON/YAML/SQL,其中XML/JSON/YAML除了具体格式语法不同,节点配置很类似,SQL格式中主要记录SQL语句,这里仅给出XML格式和SQL格式的示例,更多的格式示例请参考 官方文档

changelog.xml格式
<changeSet author="tzt" id="1">
    <createTable schemaName="ihome" tableName="user">
        <column autoIncrement="true" name="id" type="INT">
            <constraints primaryKey="true"/>
        </column>
        <column name="name" type="VARCHAR(30)"/>
    </createTable>
</changeSet>
changelog.sql格式

格式化的SQL文件使用注释为Liquibase提供元数据。每个SQL文件必须以以下注释开头:

--liquibase formatted sql
--changeset tzt:1
drop table if exists `user`;
CREATE TABLE user
(
	id  INT(9) NOT NULL COMMENT '主键ID',
	name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
	age INT(11) NULL DEFAULT NULL COMMENT '年龄',
	email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
	PRIMARY KEY (id)
);

在执行changelog的时候,会在数据库记录执行记录,主要用了下面的两张表:
1、databasechagelog
2、databasechageloglock
在这里插入图片描述

2、开始使用Liquebase

Liquibase和 Spring Boot进行整合,主要介绍如何集成应用程序进行SQL数据升级

Spring boot 本身支持Liquibase,基于maven构建的简单示例

开始接入Liquebase进行自动创建user表

1、新建一个spring boot工程 ,在pom.xml文件中添加liquebase依赖

<dependency>
	<groupId>org.liquibase</groupId>
	<artifactId>liquibase-core</artifactId>
</dependency>

2、配置application.yml(不配置使用springboot的默认配置,项目启动时会去指定目录下的数据库更改文件:resource:classpath:/db/changelog)

在resource下新建/db/changelog文件夹

spring:
  liquibase:
    enabled: true
    change-log: "classpath:/db/db.changelog-master.yml" #指定changelog配置文件
    contexts: dev

3、配置db.changelog-master.yml

  • include: file属性表示要包含的changelog文件的路径
  • includeAll: 指定的是changelog的目录,而不是为文件
databaseChangeLog:
  - include:
      file: db/changelog/init_table.sql #指定需要执行的changelog  sql文件

4、在changlog目录下新建 init_table.sql格式化的SQL文件

每个chageset更改集都用“id”属性和“author”属性唯一标识。“作者”属性可以最大限度地减少重复的可能性。

--liquibase formatted sql  
--changeset tzt:2
-- ----------------------------------------------------------
-- 感觉sql格式使用比xml舒服,每个SQL文件必须声明以上2个注释开头
-- ----------------------------------------------------------
drop table if exists `user`;
CREATE TABLE user
(
	id BIGINT(20) NOT NULL COMMENT '主键ID',
	name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
	age INT(11) NULL DEFAULT NULL COMMENT '年龄',
	email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
	PRIMARY KEY (id)
);
--rollback drop table user;

5、启动Springboot DemoApplication工程
在这里插入图片描述

查看启动日志,开始执行changelog,并执行changelog sql文件并成功创建user表
在这里插入图片描述

执行成功,demo_test库会新增的三张表
databasechangelog 数据库change的日志记录,主要包括id,author,filename等信息
databasechageloglock 表用于确保两台计算机不会同时尝试修改数据库。
在这里插入图片描述
databasechangelog记录sql执行日志
在这里插入图片描述

3、常用标签

  • 一个< changeSet >标签对应一个变更集,由属性id、name,以及changelog的文件路径唯一标识。changelog在执行的时候并不是按照id的顺序,而是按照changeSet在changelog中出现的顺序。

  • changelog中的一个changeSet对应一个事务,在changeSet执行完后commit,如果出现错误则rollback。

  • < include >与< includeAll >标签

  • < include>的file属性表示要包含的changelog文件的路径,这个文件可以是LiquiBase支持的任意格式,relativeToChangelogFile如果为true,则表示file属性表示的文件路径是相对于根changelog而不是CLASSPATH的,默认为false

  • < includeAll >指定的是changelog的目录,而不是为文件,如:

    < includeAll path="db/changelog/"/>

4、测试验证使用场景

4.1 初始化数据

新建格式化的sql文件,进行user表数据初始化

1、在/db/changelog/下面新建init_data.sql 格式化的SQL文件,用来初始化user表数据

--liquibase formatted sql 
--changeset tzt:2 
DELETE FROM user;
INSERT INTO user (id, name, age, email) VALUES(1, 'Jone', 18, 'test1@baomidou.com');
INSERT INTO user (id, name, age, email) VALUES(2, 'Jack', 20, 'test2@baomidou.com');
INSERT INTO user (id, name, age, email) VALUES(3, 'Tom', 28, 'test3@baomidou.com');
INSERT INTO user (id, name, age, email) VALUES(4, 'Sandy', 21, 'test4@baomidou.com');
INSERT INTO user (id, name, age, email) VALUES(5, 'Billie', 24, 'test5@baomidou.com');
--comment 初始化user表数据

2、在db.changelog-master.yml文件中新增格式化sql文件 init_data.sql

yml格式

databaseChangeLog:
  - include:
      file: db/changelog/init_table.sql
  - include:
      file: db/changelog/init_data.sql

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-3.4.xsd">

    <!--sql升级记录目录形式-->
    <includeAll path="classpath:db/changelog/" />

    <!--指定到具体sql文件-->
    <!--<include file="classpath:db/changelog/poweross_table.sql"/>-->

</databaseChangeLog>

3、重启程序并查看执行liquebase执行日志,表示成功插入数据:
在这里插入图片描述

4、 查看datachangelog表数据记录,可以看到变更集日志的记录,定义额变更集的描述:
在这里插入图片描述
使用场景sql执行错误并回滚数据。

1、在/db/changelog/下面新建init_data.sql 格式化的SQL文件,模拟插入主键错误并进行更新数据回滚

--liquibase formatted sql
--changeset tzt:1.1
UPDATE `demo_test`.`user` SET `id`='1', `name`='tzt', `age`='22', `email`='tang@pwoersi.com.cn' WHERE (`id`='1');  

INSERT INTO user (id, name, age, email) VALUES(2, 'zhangsan', 18, 'test1@pwoersi.com.cn');
--rollback
--comment 更新user表数据

2、在db.changelog-master.yml文件中新增格式化sql文件 update_sql1.1.sql

3、模拟版本升级,执行升级观察执行结果
在这里插入图片描述
查看数据库user表,证实没有修改成功
在这里插入图片描述

注意事项:

1、如果指定的是changelog的目录,升级时按读取文件名密码升序排序,因此会产生执行顺序问题,因此需要注意多文件命名规范:

可通过发布版本命名文件:1.0,1.1,1.2等

<includeAll path="classpath:db/changelog/" />

如下图,应该先执行poweross_table,在执行poweross_data,而实际执行顺序相反:
在这里插入图片描述

2、一个formatted sql文件changeset数据集中,按版本顺序执行,测试用例:

tzt:1.1数据集执行后,执行 tzt:1.2版本数据集,当1.1执行失败后,将抛出异常终止执行。

--liquibase formatted sql
--changeset tzt:1.1
INSERT INTO user (id, name, age, email) VALUES(2, 'zhangsan', 18, 'test1@pwoersi.com.cn');
--rollback 2
--comment 更新user表数据

--changeset tzt:1.2
INSERT INTO user (id, name, age, email) VALUES(6, 'lisi', 24, 'lisi@pwoersi.com.cn');
UPDATE `demo_test`.`user` SET `id`='5', `name`='TTTT', `age`='24', `email`='test5@baomidou.com' WHERE (`id`='5');
alter table user des varchar(20) comment '说明';
INSERT INTO user (id, name, age, email) VALUES(7, 'lll', 18, 'lisi@pwoersi.com.cn');

--rollback
--comment 新增字段dec

执行错误日志:
在这里插入图片描述
3、changeset数据集增加字段错误,数据无法回滚

--changeset tzt:1.2
INSERT INTO user (id, name, age, email) VALUES(6, 'lisi', 24, 'lisi@pwoersi.com.cn');
UPDATE `demo_test`.`user` SET `id`='5', `name`='TTTT', `age`='24', `email`='test5@baomidou.com' WHERE (`id`='5');
ALTER TABLE `user` ADD COLUMN decscc VARCHAR(100) DEFAULT NULL COMMENT '描述';  #此处报错,后面sql无法执行
ALTER TABLE `user` DROP COLUMN decs;  
INSERT INTO user (id, name, age, email) VALUES(7, 'lll', 18, 'lisi@pwoersi.com.cn');
--rollback
--comment 新增字段dec

执行日志
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值