文章目录

  • 概述
    • 环境
      • 软件程序
        • 安装
          • Windows
          • Linux
          • GitHub Action - 自动化工作流
        • 常用命令
          • 免费
          • 收费
        • 使用
          • generate-changelog-配置文件 - liquibase.properties
          • update - 将变更表变化内容真正作用于数据库中
          • update-sql - 仅用于生成真正的SQL语句
          • db-doc - 数据库文档生成
          • lock - 锁,liquibase同一时间仅能一个用户去变更数据库结构
          • snapshot - 记录某时刻的数据库结构快照
          • diff - 两个数据库之间表结构比对工具
          • diff-changelog - 生成一个与源库结构之间表结构差异的changelog文件
          • rollback-count、rollback-count-sql - 回滚某个changelog文件最新部署的某N条变更,以及查看待回滚的SQL
          • rollback-to-date、 rollback-to-date-sql - 回滚某个changelog文件最新部署到某天日期的结构,以及查看待回滚的SQL
      • Java
        • SpringBoot
    • 内置表-只要运行则自动生成两个表用来记录liquibase的运行情况
    • databaseChangeLog文件语法
      • XML
        • 最简单Demo
        • changeSet - 执行的变更节点
        • Preconditions-先决条件
          • preConditions的属性
          • 案例讲解
        • include、includeAll-databaseChangeLog文件的囊括,更细化的管理数据库变更

概述

官网文档: https://docs.liquibase.com/concepts/changelogs/working-with-changelogs.html

支持的数据库: https://docs.liquibase.com/install/supported-databases.html

环境

软件程序

安装
Windows

下载地址: https://github.com/liquibase/liquibase/releases

Linux

下载地址: https://github.com/liquibase/liquibase/releases

//wget  右键上面图片的选项,获取下载地址
wget https://github.com/liquibase/liquibase/releases/download/v4.12.0/liquibase-4.12.0.tar.gz//解压
tar -zxxf liquibase-4.12.0.tar.gz//编辑
vi /etc/profile
//  文件/etc/profile里面末尾添加如下内容
PATH=$PATH:/www/server/liquibase//让文件/etc/profile在系统中重新生效
source /etc/profle//查看liquibase命令是否可用
liquibase --help
liquibase --version

GitHub Action - 自动化工作流

官方文档: https://docs.liquibase.com/workflows/liquibase-community/setup-github-actions-workflow.html

常用命令
免费
//版本
liquibase --version//查看liquibase支持的所有命令
liquibase --help//查看此个命令支持的参数选项信息
liquibase 命令 --help//查看目标数据库是否能连接成功、pro证书信息是否有效(使用高级命令)
//当前目录需要有liquibase.properties文件
liquibase status//前提:当前目录必须有liquibase.properties文件
//基于数据库信息生成一份原始changeLogFile文件
//数据库结构快照备份,备份完之后修改liquibase.properties的地址,运行 liquibase update 可快速迁移无需一个一个创建
liquibase generate-changelog//前提:当前目录必须有liquibase.properties文件以及liquibase.properties定义的changeLogFile文件
//基于liquibase.properties属性里面定义的changeLogFile文件来更新、修改数据库
liquibase update//前提:当前目录必须有liquibase.properties文件以及liquibase.properties定义的changeLogFile文件
//基于liquibase.properties属性里面定义的changeLogFile文件来更新、修改数据库(最多仅更新10个未部署的<changgeset>的语句,如果某个changeset之前已经部署过就不算)
liquibase updateCount 部署changeset节点的个数//前提:当前目录必须有liquibase.properties文件以及liquibase.properties定义的changeLogFile文件
//基于changeLogFile的文件生成具体的真正可在数据库运行的SQL语句 == 仅仅生成SQL语句不会在数据库中生效,如果想让SQL语句的数据库生效请使用 liquibase update
liquibase update-sql//其实就是展示databasechangelog的记录:FILENAME、ID、AUTHOR、DEPLOYMENT_ID
liquibase history//比对数据库结构
//选项参数参看:liquibase diff --help
//liquibase diff
//将比对结果保存在当前目录的diff.txt目录中  == 结果形式看下面的图片即可
//liquibase diff   --outputFile=diff.txt
//将比对结果保存在当前目录的diff.json目录中,且内容格式是json,结构化数据
//liquibase diff  --format=json --outputFile=diff.json
liquibase diff//生成的文件,表示当前目标数据库在源库表结构相差的东西
//生成的文件最后可以使用(使得目标库与源库结构一致):liquibase update --changelog-file=diffChangelog.xml
liquibase diff-changelog --changelog-file=diffChangelog.xml//生成数据库结构、changlog文件内容显示 -- 仅能生成html文档
liquibase db-doc --output-directory=文档输出目录//查看当前是否有用户在运行liquibase更改数据库结构 == 即表DATABASECHANGELOGLOCK是否有LOCKED=1的记录
liquibase list-locks//释放锁 = 将表DATABASECHANGELOGLOCK的LOCKED=1的记录,修改LOCKED=0且将被锁的开始时间LOCKGRANTED、使用锁的IP地址LOCKEDBY都置空
//一般来说用不上,因为liquibase正常变更、退出会自动释放锁,如果非正常退出可能锁的状态没来得及释放,需要你手动执行该条命令释放,或者直接去数据库修改锁状态设为0即可
liquibase release-locks//数据库结构快照 == 感觉跟 generate-changgelog差不多 == 文件存放在当前目录下
liquibase --outputFile=snapshot.text  snapshot --snapshot-format=text
liquibase --outputFile=snapshot.yml  snapshot --snapshot-format=yml
liquibase --outputFile=snapshot.json  snapshot --snapshot-format=json//表结构回滚
liquibase rollback 标签名//基于某个changelog文件,表结构回滚最新部署的某几条变更(将SQL作用到数据库,建议使用这条命令前,先用 rollback-count-sql确认一下SQL语句)
liquibase rollback-count  回滚最新部署的条数
//基于某个changelog文件,表结构回滚最新部署的SQL查看(未作用SQL部署到数据库,仅是看SQL的命令而已)
liquibase rollback-count-sql 回滚最新部署的条数//表结构回滚到某一个时间节点的部署 == 原本部署的是新增,回滚即是删除,如果原本部署的是删除,回滚新增是不支持的
//下面的语句是等价于  liquibase rollback-to-date  yyyy-MM-dd 00:00:00
liquibase rollback-to-date  yyyy-MM-dd
//具体的时间节点 -- 更建议加上详细的时间点上去
liquibase rollback-to-date  yyyy-MM-dd HH:mm:ss

liquibase状态、数据库连接是否生效、pro证书是否有效



部署历史:liquibase history


结构比对:liquibase diff

changeLogFile: changelog.xml
driver: com.mysql.cj.jdbc.Driver
classpath: G:/Maven/repository/mysql/mysql-connector-java/8.0.29/mysql-connector-java-8.0.29.jar
liquibase.hub.mode=off
# 数据库名
includeSchema=falseincludeCatalog=false# 不使用收费命令,这个配置可以不用设置哦 == 如数据库回滚操作就是收费的
liquibaseProLicenseKey=ABwwGgQUOxlA3aIJheBLWs6hMt67/uF460QCAgQAaXEr2Xr4ybHQcJ2HAD5XCXfdr96miPZiaZj54VwMs5uo5Pvk8IVP7dB7Du3ig7qj3OsF0NrGk/kyjmKK6oFG8CEWxtDh0sQ0zJVcf0AffvUftK019nl9p2qi+hfJgEl00OLQSqdCXT2J562QtNAzmsVE8ubg5SmK6+oiLlODnYx++jPjQ98o4aRbvOygNrTAoIFBot8Gf1kmcD5IS9p/6QpoIGw/8l9EM/gyoDY/euMRAVGg2OWVqKhFBD6XLXxgF2SL5d8LhvvBpGfP00RWWtqMxD+8ukuh/mLcS5+w0ERH0Do6Y0Y3H4C2tGpngULv9iqoVfz9idLozyNQpMWgLwAZttL5S7Tguy5CTtFzd5Dm8Pp+0A6e6XEAeFiwE+OPr54KcQeMOy6dSHWtgE6d4ktlX84q4JS15yTPyoFFHiClndPSlV5inj4GPN3wjntGL5fVlJBldO+XeAt2PDGTKlGHpHR3MoZ/YcRrhL/rEMWFBi6HE4mvp5dkIj3vE4wQoj7roA6hiquxwmzfDcwpBIBpnVFZqPoD2MTS0CqJLkJkLU9azQxZfDtp1ZAn/r/RsnmgbDJTDE10TT5/Tj2EyO9eCf1KRR/CjLGywftpJX0x6rlsDrAfZtDJ7ZETld72RR8XWmkuIkPInISYhdDSaCGu9s0BS4rB# 目标数据库 == 部署SQL会在这里运行
url: jdbc:mysql://localhost:3306/lrc_blog_test4?useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: root# 源数据库
referenceUrl: jdbc:mysql://localhost:3306/lrc_blog?useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
referenceUsername: root
referencePassword: root

收费

# 想删除数据库中article_category表   --changeset-path基于什么文件进行回滚
# 如果是<sql>节点类型,则不能回滚
# 如果是<createTable>类型的节点,非具体SQL才能回滚
liquibase rollback-one-changeset-sql --changeset-author="Administrator (generated)" --changeset-id="1656816165512-3" --changeset-path=changelog.xml


可惜此条命令是收费功能,需要使用liquibase pro才行

配置证书后运行





//回滚某次的部署的话  ==  真正实行的SQL语句查看
liquibase rollback-one-update-sql --deployment-id=6835018522//真正的通过liquibase执行回滚-不考虑后果强制执行 == 将上述的SQL语句结果真正运行到数据库中
liquibase rollback-one-update --deployment-id=6835018522 --force

使用
generate-changelog-配置文件 - liquibase.properties

generate-changelog官网文档: https://docs.liquibase.com/commands/snapshot/generate-changelog.html?Highlight=generate-changelog

liquibase.properties官网文档: https://docs.liquibase.com/concepts/connections/creating-config-properties.html

liquibase.properties - 数据库相关的文件配置

# 支持生成changelog.xml、changelog.json、changelog.yml,changelog.sql,直接改后缀即可、liquibase自动会识别将要生成额类型
changeLogFile: changelog.xml
driver: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/lrc_blog_test?useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
username: root
password: root
classpath: G:/Maven/repository/mysql/mysql-connector-java/8.0.29/mysql-connector-java-8.0.29.jar

开始生成Liquibase管理的changlog.xml文件

//执行此命令的前提是必须要有前面的liquibase.properties数据库相关的信息  == 生成的changelog.xml内容会基于数据库的表信息生成一份(用于记录备份原始表结构之类的),数据库没有表则是空信息
liquibase generate-changelog

update - 将变更表变化内容真正作用于数据库中

update-sql - 仅用于生成真正的SQL语句

db-doc - 数据库文档生成

官方文档: https://docs.liquibase.com/commands/docs/db-doc.html

文档生成

nginx指定db-doc目录

浏览器查看-文档内容

lock - 锁,liquibase同一时间仅能一个用户去变更数据库结构

原理: 表DATABASECHANGELOGLOCK

//显示数据库是否有锁
liquibase list-locks//释放锁
liquibase release-locks

snapshot - 记录某时刻的数据库结构快照

官方文档: https://docs.liquibase.com/commands/snapshot/snapshot.html

//支持三种格式输出:--snapshot-format=text、json、yml
liquibase --outputFile=snapshot.yml  snapshot --snapshot-format=yml

diff - 两个数据库之间表结构比对工具

官方文档: https://docs.liquibase.com/commands/diff/diff.html

//将比对的内容信息输出到diff.txt文件中
liquibase diff  --output-file=diff.txt

diff-changelog - 生成一个与源库结构之间表结构差异的changelog文件

**官方文档:**https://docs.liquibase.com/commands/diff/diff-changelog.html

//生成的文件,表示当前目标数据库在源库表结构相差的东西
liquibase diff-changelog --changelog-file=diffChangelog.xml//使用上面生成的changlog文件,将缺失的表结构更新到目标数据库中
liquibase update --changelog-file=diffChangelog.xml

rollback-count、rollback-count-sql - 回滚某个changelog文件最新部署的某N条变更,以及查看待回滚的SQL

官网: https://docs.liquibase.com/commands/rollback/rollback-count.html

注意: 只能回滚新增,即changelog原先定义的且已经部署的是create xx,可以使用liquibase的回滚功能,即直接liquibase是删对象即可,如果你回滚删除,liquibase是不支持的。

rollback-to-date、 rollback-to-date-sql - 回滚某个changelog文件最新部署到某天日期的结构,以及查看待回滚的SQL

官网: https://docs.liquibase.com/commands/rollback/rollback-count.html

注意: 只能回滚新增,即changelog原先定义的且已经部署的是create xx,可以使用liquibase的回滚功能,即直接liquibase直接删即可,如果你回滚删除,liquibase是不支持的。

Java

SpringBoot

文档: https://docs.liquibase.com/tools-integrations/springboot/using-springboot-with-maven.html

依赖

<!-- https://mvnrepository.com/artifact/org.liquibase/liquibase-core -->
<dependency><groupId>org.liquibase</groupId><artifactId>liquibase-core</artifactId><version>4.12.0</version>
</dependency>

配置文件application.yml

spring:liquibase:enabled: truechange-log: classpath:/db/changelog/db.changelog-master.xmldatasource:username: rootpassword: rooturl: jdbc:mysql://localhost:3306/lrc_blog_test?useSSL=false&characterEncoding=UTF-8&serverTimezone=Asia/Shanghaidriver-class-name: com.mysql.cj.jdbc.Driver

db.changelog-master.xml

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="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"xmlns:pro="http://www.liquibase.org/xml/ns/pro"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangeloghttp://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsdhttp://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsdhttp://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd"><includeAll path="change" relativeToChangelogFile="true" errorIfMissingOrEmpty="false" ></includeAll></databaseChangeLog>


v1.20220702xml

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="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"xmlns:pro="http://www.liquibase.org/xml/ns/pro"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangeloghttp://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsdhttp://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsdhttp://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd"><changeSet id="1" author="LinRuChang" ><preConditions onFail="CONTINUE" onError="CONTINUE" onFailMessage="test_table表已存在" onErrorMessage="执行1:LinRuChang的前置条件过程中发生异常"><not><tableExists tableName="test_table"></tableExists></not></preConditions><comment>创建表test_table</comment><sql>CREATE TABLE `test_table`(`id`          char(32) CHARACTER SET utf8 COLLATE utf8_bin        NOT NULL COMMENT '主键',`name`        varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '角色名',PRIMARY KEY (`id`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='liquibase测试表'</sql></changeSet><changeSet id="3" author="LinRuChang" ><preConditions onFail="CONTINUE" onError="CONTINUE" onFailMessage="test_table3表已存在" onErrorMessage="执行3:LinRuChang的前置条件过程中发生异常"><not><tableExists tableName="test_table3"></tableExists></not></preConditions><comment>创建表test_table3</comment><sql>CREATE TABLE `test_table3`(`id`          char(32) CHARACTER SET utf8 COLLATE utf8_bin        NOT NULL COMMENT '主键',`name`        varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '角色名',PRIMARY KEY (`id`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='liquibase测试表'</sql></changeSet><changeSet author="Administrator (generated)" id="1656816165512-1"><preConditions onFail="CONTINUE" onError="CONTINUE" onFailMessage="article表已存在" onErrorMessage="执行1:LinRuChang的前置条件过程中发生异常"><not><tableExists tableName="article2"></tableExists></not></preConditions><comment>创建表article2</comment><createTable remarks="文章表" tableName="article2"><column name="id" remarks="主键id" type="CHAR(32)"><constraints nullable="false" primaryKey="true"/></column><column name="status" remarks="文章状态;-1违规 0草稿 1发布且公开  2发布且私密" type="VARCHAR(255)"/><column name="title" remarks="文章标题" type="VARCHAR(100)"/><column defaultValue="1" name="type" remarks="文章内容类型:1富文本 2Markdown 3留空" type="VARCHAR(255)"/><column name="content" remarks="文章内容" type="TEXT"/><column name="abbreviation_content" remarks="缩略文章,最大200字符,从content抽出的纯文本内容" type="VARCHAR(255)"/><column name="img_url" remarks="列表文章的图片显示 - 如果指定则使用指定的图片(功能未做),没有指定则使用文章第一张图片,在没有则使用文章中有图标则使用目录分裂的图片" type="VARCHAR(1000)"/><column name="img_urls" remarks="文章内部图片 - 七彩牛CDN" type="VARCHAR(15000)"/><column name="check_num" remarks="文章被查看次数" type="INT"/><column name="like_num" remarks="当前文章被点赞数" type="INT"/><column name="not_like_num" remarks="当前文章不喜欢数" type="INT"/><column name="create_time" remarks="文章创建时间 - 格式 - yyyyMMddHHmmss" type="CHAR(30)"><constraints nullable="false"/></column><column name="create_by" remarks="创建者 - 冗余字段 - user表的nickName" type="VARCHAR(255)"/><column name="update_time" remarks="记录更新时间 - 格式 - yyyyMMddHHmmss" type="CHAR(30)"><constraints nullable="false"/></column><column defaultValueBoolean="false" name="is_del" remarks="该记录是否被逻辑删除:0未删除 1逻辑删除" type="BIT(1)"><constraints nullable="false"/></column><column defaultValueBoolean="false" name="is_violation" remarks="文章是否违规:0未违规 1违规 - 违规不可显示" type="BIT(1)"><constraints nullable="false"/></column><column defaultValueNumeric="0" name="version" remarks="乐观锁(记录的被修改数)" type="INT"/></createTable></changeSet></databaseChangeLog>


v1.20220703.xml

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="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"xmlns:pro="http://www.liquibase.org/xml/ns/pro"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangeloghttp://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsdhttp://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsdhttp://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd"><changeSet id="2" author="LinRuChang"  ><preConditions onFail="CONTINUE" onError="CONTINUE" onFailMessage="test_table表已存在2" onErrorMessage="执行1:LinRuChang的前置条件过程中发生异常"><not><tableExists tableName="test_table2"></tableExists></not></preConditions><comment>创建表test_table2</comment><sql>CREATE TABLE `test_table2`(`id`          char(32) CHARACTER SET utf8 COLLATE utf8_bin        NOT NULL COMMENT '主键',`name`        varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '角色名',PRIMARY KEY (`id`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='liquibase测试表'</sql></changeSet>
</databaseChangeLog>

//直接启动springBoot程序即可,liquibase会自动运行,准备修改数据库的表结构

内置表-只要运行则自动生成两个表用来记录liquibase的运行情况

背景: 部署更改时,Liquibase 会在数据库中创建两个表:DATABASECHANGELOG 和 DATABASECHANGELOGLOCK

变更执行顺序: 按节点在文件内容中编辑顺序执行,而不是由id+author+filename顺序执行

DATABASECHANGELOG表介绍: https://docs.liquibase.com/concepts/tracking-tables/databasechangelog-table.html

DATABASECHANGELOGLOCK表介绍: https://docs.liquibase.com/concepts/tracking-tables/databasechangeloglock-table.html


变更的唯一标识组成: author + id + 当前changeset节点所在的文件名


databasechangelog:EXECTYPE是EXECUTED下次变更则不在运行此个changset节点内容

databasechangeloglock:仅能有一个用户进行变更表结构操作,如果另一个用户也同时启动项目它则需要等待前面用户执行完才能继续部署触发变更操作==即LOCKED=1表明已经有人在触发变更操作,需要等到它变至为0,或手动修改为0才能触发另一个用户触发变更

databaseChangeLog文件语法

XML

所有XML节点介绍官方文档: https://docs.liquibase.com/change-types/home.html

最简单Demo

v1.20220702.xml

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="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"xmlns:pro="http://www.liquibase.org/xml/ns/pro"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangeloghttp://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsdhttp://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsdhttp://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd"><changeSet id="1" author="LinRuChang"><preConditions onFail="CONTINUE"><not><tableExists tableName="test_table"></tableExists></not></preConditions><sql>CREATE TABLE `test_table`(`id`          char(32) CHARACTER SET utf8 COLLATE utf8_bin        NOT NULL COMMENT '主键',`name`        varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '角色名',`create_time` char(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '用户创建时间 - 格式 - yyyyMMddHHmmss',`update_time` char(30) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '记录更新时间 - 格式 - yyyyMMddHHmmss',`is_del`      tinyint(1) NOT NULL DEFAULT '0' COMMENT '该记录是否被逻辑删除:0未删除 1逻辑删除',`version`     int(8) DEFAULT '0' COMMENT '乐观锁(记录的被修改数)',PRIMARY KEY (`id`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='liquibase测试表'</sql></changeSet>
</databaseChangeLogxmlns="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"xmlns:pro="http://www.liquibase.org/xml/ns/pro"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangeloghttp://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsdhttp://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsdhttp://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd">


db.changelog-master.xml

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="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"xmlns:pro="http://www.liquibase.org/xml/ns/pro"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangeloghttp://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsdhttp://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsdhttp://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd"><include file="change/v1.20220702.xml" relativeToChangelogFile="true"></include></databaseChangeLog>

changeSet - 执行的变更节点

官方:一个变更建议使用一个changgeset,不要多个变更放在一个节点上


changeSet支持的属性

Preconditions-先决条件

作用: 执行SQL变更操作前的判断,如果不符合(先决条件false)则报错即项目启动失败(默认),我一般设置成先决条件为false都会跳过当前这个变更操作

官方文档: https://docs.liquibase.com/concepts/changelogs/preconditions.html

preConditions的属性
#mermaid-svg-047A2VxoO8RxFQif {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-047A2VxoO8RxFQif .error-icon{fill:#552222;}#mermaid-svg-047A2VxoO8RxFQif .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-047A2VxoO8RxFQif .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-047A2VxoO8RxFQif .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-047A2VxoO8RxFQif .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-047A2VxoO8RxFQif .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-047A2VxoO8RxFQif .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-047A2VxoO8RxFQif .marker{fill:#333333;stroke:#333333;}#mermaid-svg-047A2VxoO8RxFQif .marker.cross{stroke:#333333;}#mermaid-svg-047A2VxoO8RxFQif svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-047A2VxoO8RxFQif .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-047A2VxoO8RxFQif .cluster-label text{fill:#333;}#mermaid-svg-047A2VxoO8RxFQif .cluster-label span{color:#333;}#mermaid-svg-047A2VxoO8RxFQif .label text,#mermaid-svg-047A2VxoO8RxFQif span{fill:#333;color:#333;}#mermaid-svg-047A2VxoO8RxFQif .node rect,#mermaid-svg-047A2VxoO8RxFQif .node circle,#mermaid-svg-047A2VxoO8RxFQif .node ellipse,#mermaid-svg-047A2VxoO8RxFQif .node polygon,#mermaid-svg-047A2VxoO8RxFQif .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-047A2VxoO8RxFQif .node .label{text-align:center;}#mermaid-svg-047A2VxoO8RxFQif .node.clickable{cursor:pointer;}#mermaid-svg-047A2VxoO8RxFQif .arrowheadPath{fill:#333333;}#mermaid-svg-047A2VxoO8RxFQif .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-047A2VxoO8RxFQif .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-047A2VxoO8RxFQif .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-047A2VxoO8RxFQif .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-047A2VxoO8RxFQif .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-047A2VxoO8RxFQif .cluster text{fill:#333;}#mermaid-svg-047A2VxoO8RxFQif .cluster span{color:#333;}#mermaid-svg-047A2VxoO8RxFQif div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-047A2VxoO8RxFQif :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

preConditions属性
onFail:先决条件得到的结果是false的情况下的处理方案
onError:先决条件执行的过程中发生异常情况下的处理方案
onFailMessage:先决条件为false时的日志信息
onErrorMessage:先决条件发生异常时的日志信息
onSqlOutput:这玩意看文档没看懂是干嘛的
#mermaid-svg-ap2zHphK0TUSXXjJ {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-ap2zHphK0TUSXXjJ .error-icon{fill:#552222;}#mermaid-svg-ap2zHphK0TUSXXjJ .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-ap2zHphK0TUSXXjJ .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-ap2zHphK0TUSXXjJ .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-ap2zHphK0TUSXXjJ .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-ap2zHphK0TUSXXjJ .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-ap2zHphK0TUSXXjJ .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-ap2zHphK0TUSXXjJ .marker{fill:#333333;stroke:#333333;}#mermaid-svg-ap2zHphK0TUSXXjJ .marker.cross{stroke:#333333;}#mermaid-svg-ap2zHphK0TUSXXjJ svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-ap2zHphK0TUSXXjJ .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-ap2zHphK0TUSXXjJ .cluster-label text{fill:#333;}#mermaid-svg-ap2zHphK0TUSXXjJ .cluster-label span{color:#333;}#mermaid-svg-ap2zHphK0TUSXXjJ .label text,#mermaid-svg-ap2zHphK0TUSXXjJ span{fill:#333;color:#333;}#mermaid-svg-ap2zHphK0TUSXXjJ .node rect,#mermaid-svg-ap2zHphK0TUSXXjJ .node circle,#mermaid-svg-ap2zHphK0TUSXXjJ .node ellipse,#mermaid-svg-ap2zHphK0TUSXXjJ .node polygon,#mermaid-svg-ap2zHphK0TUSXXjJ .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-ap2zHphK0TUSXXjJ .node .label{text-align:center;}#mermaid-svg-ap2zHphK0TUSXXjJ .node.clickable{cursor:pointer;}#mermaid-svg-ap2zHphK0TUSXXjJ .arrowheadPath{fill:#333333;}#mermaid-svg-ap2zHphK0TUSXXjJ .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-ap2zHphK0TUSXXjJ .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-ap2zHphK0TUSXXjJ .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-ap2zHphK0TUSXXjJ .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-ap2zHphK0TUSXXjJ .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-ap2zHphK0TUSXXjJ .cluster text{fill:#333;}#mermaid-svg-ap2zHphK0TUSXXjJ .cluster span{color:#333;}#mermaid-svg-ap2zHphK0TUSXXjJ div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-ap2zHphK0TUSXXjJ :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

默认值
建议都设置成这个
onFail的属性值:校验是false的情况
HALT:暂停整个更改日志的执行,项目直接抛出异常导致项目启动失败
CONTINUE:跳过变更集。下次更新时将再次尝试执行变更集。下次启动项目会尝试继续执行该changeSet节点
MARK_RAN:跳过变更集,但将其标记为已执行,下次启动项目不在执行该changeSet节点
WARN:发送警告并继续正常执行变更集,即是校验失败也继续执行changeSet节点中定义的SQL语句,依然可能会导致启动失败,如创表语句必失败,但修改表结构可能不会失败
#mermaid-svg-jcWMgJLsaCU3tPrG {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-jcWMgJLsaCU3tPrG .error-icon{fill:#552222;}#mermaid-svg-jcWMgJLsaCU3tPrG .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-jcWMgJLsaCU3tPrG .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-jcWMgJLsaCU3tPrG .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-jcWMgJLsaCU3tPrG .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-jcWMgJLsaCU3tPrG .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-jcWMgJLsaCU3tPrG .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-jcWMgJLsaCU3tPrG .marker{fill:#333333;stroke:#333333;}#mermaid-svg-jcWMgJLsaCU3tPrG .marker.cross{stroke:#333333;}#mermaid-svg-jcWMgJLsaCU3tPrG svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-jcWMgJLsaCU3tPrG .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-jcWMgJLsaCU3tPrG .cluster-label text{fill:#333;}#mermaid-svg-jcWMgJLsaCU3tPrG .cluster-label span{color:#333;}#mermaid-svg-jcWMgJLsaCU3tPrG .label text,#mermaid-svg-jcWMgJLsaCU3tPrG span{fill:#333;color:#333;}#mermaid-svg-jcWMgJLsaCU3tPrG .node rect,#mermaid-svg-jcWMgJLsaCU3tPrG .node circle,#mermaid-svg-jcWMgJLsaCU3tPrG .node ellipse,#mermaid-svg-jcWMgJLsaCU3tPrG .node polygon,#mermaid-svg-jcWMgJLsaCU3tPrG .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-jcWMgJLsaCU3tPrG .node .label{text-align:center;}#mermaid-svg-jcWMgJLsaCU3tPrG .node.clickable{cursor:pointer;}#mermaid-svg-jcWMgJLsaCU3tPrG .arrowheadPath{fill:#333333;}#mermaid-svg-jcWMgJLsaCU3tPrG .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-jcWMgJLsaCU3tPrG .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-jcWMgJLsaCU3tPrG .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-jcWMgJLsaCU3tPrG .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-jcWMgJLsaCU3tPrG .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-jcWMgJLsaCU3tPrG .cluster text{fill:#333;}#mermaid-svg-jcWMgJLsaCU3tPrG .cluster span{color:#333;}#mermaid-svg-jcWMgJLsaCU3tPrG div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-jcWMgJLsaCU3tPrG :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

默认值
建议都设置成这个
onError的属性值:校验语句发生异常的时候
HALT:暂停整个更改日志的执行,项目直接抛出异常导致项目启动失败
CONTINUE:跳过变更集。下次更新时将再次尝试执行变更集。下次启动项目会尝试继续执行该changeSet节点
MARK_RAN:跳过变更集,但将其标记为已执行,下次启动项目不在执行该changeSet节点
WARN:发送警告并继续正常执行变更集,即是校验失败也继续执行changeSet节点中定义的SQL语句,依然可能会导致启动失败,如创表语句必失败,但修改表结构可能不会失败
案例讲解

<?xml version="1.0" encoding="UTF-8"?>
<databaseChangeLogxmlns="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"xmlns:pro="http://www.liquibase.org/xml/ns/pro"xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangeloghttp://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-latest.xsdhttp://www.liquibase.org/xml/ns/dbchangelog-ext http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-ext.xsdhttp://www.liquibase.org/xml/ns/pro http://www.liquibase.org/xml/ns/pro/liquibase-pro-latest.xsd"><changeSet id="1" author="LinRuChang"><!--如果test_table不存在则执行下面的sql节点的sql语句,如果存在,onFail=HALT默认即直接抛出异常终止项目,所以我改成onFail="CONTINUE"跳过当前这个changeSet节点,继续执行其他节点 --><preConditions onFail="CONTINUE" onError="CONTINUE" onFailMessage="test_table表已存在" onErrorMessage="执行1:LinRuChang的前置条件过程中发生异常"><not><tableExists tableName="test_table"></tableExists></not></preConditions><sql>CREATE TABLE `test_table`(`id`          char(32) CHARACTER SET utf8 COLLATE utf8_bin        NOT NULL COMMENT '主键',`name`        varchar(255) CHARACTER SET utf8 COLLATE utf8_bin DEFAULT NULL COMMENT '角色名',PRIMARY KEY (`id`) USING BTREE) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='liquibase测试表'</sql></changeSet></databaseChangeLog>

include、includeAll-databaseChangeLog文件的囊括,更细化的管理数据库变更

include官网介绍: https://docs.liquibase.com/concepts/changelogs/attributes/include.html

includeall官网介绍: https://docs.liquibase.com/concepts/changelogs/attributes/includeall.html

此两个节点属性作用,请参考源码: liquibase.changelog.DatabaseChangeLog#handleChildNode

#mermaid-svg-0L4sdLj4pJZ7qiKS {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-0L4sdLj4pJZ7qiKS .error-icon{fill:#552222;}#mermaid-svg-0L4sdLj4pJZ7qiKS .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-0L4sdLj4pJZ7qiKS .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-0L4sdLj4pJZ7qiKS .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-0L4sdLj4pJZ7qiKS .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-0L4sdLj4pJZ7qiKS .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-0L4sdLj4pJZ7qiKS .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-0L4sdLj4pJZ7qiKS .marker{fill:#333333;stroke:#333333;}#mermaid-svg-0L4sdLj4pJZ7qiKS .marker.cross{stroke:#333333;}#mermaid-svg-0L4sdLj4pJZ7qiKS svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-0L4sdLj4pJZ7qiKS .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-0L4sdLj4pJZ7qiKS .cluster-label text{fill:#333;}#mermaid-svg-0L4sdLj4pJZ7qiKS .cluster-label span{color:#333;}#mermaid-svg-0L4sdLj4pJZ7qiKS .label text,#mermaid-svg-0L4sdLj4pJZ7qiKS span{fill:#333;color:#333;}#mermaid-svg-0L4sdLj4pJZ7qiKS .node rect,#mermaid-svg-0L4sdLj4pJZ7qiKS .node circle,#mermaid-svg-0L4sdLj4pJZ7qiKS .node ellipse,#mermaid-svg-0L4sdLj4pJZ7qiKS .node polygon,#mermaid-svg-0L4sdLj4pJZ7qiKS .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-0L4sdLj4pJZ7qiKS .node .label{text-align:center;}#mermaid-svg-0L4sdLj4pJZ7qiKS .node.clickable{cursor:pointer;}#mermaid-svg-0L4sdLj4pJZ7qiKS .arrowheadPath{fill:#333333;}#mermaid-svg-0L4sdLj4pJZ7qiKS .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-0L4sdLj4pJZ7qiKS .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-0L4sdLj4pJZ7qiKS .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-0L4sdLj4pJZ7qiKS .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-0L4sdLj4pJZ7qiKS .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-0L4sdLj4pJZ7qiKS .cluster text{fill:#333;}#mermaid-svg-0L4sdLj4pJZ7qiKS .cluster span{color:#333;}#mermaid-svg-0L4sdLj4pJZ7qiKS div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-0L4sdLj4pJZ7qiKS :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

节点
include:某个databaseChangeLog具体的文件路径
includeAll:某个目录下的所有databaseChangeLog文件

include所有属性

includeAll所有属性

#mermaid-svg-eiwQouuKRQ6nOxwu {font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}#mermaid-svg-eiwQouuKRQ6nOxwu .error-icon{fill:#552222;}#mermaid-svg-eiwQouuKRQ6nOxwu .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-eiwQouuKRQ6nOxwu .edge-thickness-normal{stroke-width:2px;}#mermaid-svg-eiwQouuKRQ6nOxwu .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-eiwQouuKRQ6nOxwu .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-eiwQouuKRQ6nOxwu .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-eiwQouuKRQ6nOxwu .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-eiwQouuKRQ6nOxwu .marker{fill:#333333;stroke:#333333;}#mermaid-svg-eiwQouuKRQ6nOxwu .marker.cross{stroke:#333333;}#mermaid-svg-eiwQouuKRQ6nOxwu svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-eiwQouuKRQ6nOxwu .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-eiwQouuKRQ6nOxwu .cluster-label text{fill:#333;}#mermaid-svg-eiwQouuKRQ6nOxwu .cluster-label span{color:#333;}#mermaid-svg-eiwQouuKRQ6nOxwu .label text,#mermaid-svg-eiwQouuKRQ6nOxwu span{fill:#333;color:#333;}#mermaid-svg-eiwQouuKRQ6nOxwu .node rect,#mermaid-svg-eiwQouuKRQ6nOxwu .node circle,#mermaid-svg-eiwQouuKRQ6nOxwu .node ellipse,#mermaid-svg-eiwQouuKRQ6nOxwu .node polygon,#mermaid-svg-eiwQouuKRQ6nOxwu .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-eiwQouuKRQ6nOxwu .node .label{text-align:center;}#mermaid-svg-eiwQouuKRQ6nOxwu .node.clickable{cursor:pointer;}#mermaid-svg-eiwQouuKRQ6nOxwu .arrowheadPath{fill:#333333;}#mermaid-svg-eiwQouuKRQ6nOxwu .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-eiwQouuKRQ6nOxwu .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-eiwQouuKRQ6nOxwu .edgeLabel{background-color:#e8e8e8;text-align:center;}#mermaid-svg-eiwQouuKRQ6nOxwu .edgeLabel rect{opacity:0.5;background-color:#e8e8e8;fill:#e8e8e8;}#mermaid-svg-eiwQouuKRQ6nOxwu .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-eiwQouuKRQ6nOxwu .cluster text{fill:#333;}#mermaid-svg-eiwQouuKRQ6nOxwu .cluster span{color:#333;}#mermaid-svg-eiwQouuKRQ6nOxwu div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-eiwQouuKRQ6nOxwu :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;}

仅include
仅include
仅include
仅includeAll
仅include
仅include
仅include
仅includeAll
仅includeAll
仅includeAll
属性
id:databaseChangeLog的ID
author:databaseChangeLog的作者
file:需要引入的databaseChangeLog文件、目录地址
path:需要引入的databaseChangeLog文件所在的目录地址==会囊括此目录以及子目录里面所有的atabaseChangeLog文件
relativeToChangelogFile:true则file的路径是以当前文件的相对路径为准,false(默认)以classpath路径为准
context:
labels:
ignore:
created:
errorIfMissingOrEmpty:true如果扫到目录没任何databaseChangeLog的文件则抛出异常,导致项目启动失败,false则不抛出异常直接忽略这种情况,项目启动成功
resourceComparator:Comparator的实现类,入参是基于classpath的databaseChangeLog文件路径字符串,用于排序优先加载databaseChangeLog文件而已,默认是liquibase.changelog.DatabaseChangeLog#getStandardChangeLogComparator
filter:实现liquibase.changelog.IncludeAllFilter接口,填实现类的全限定名进去,形参是基于classpath的databaseChangeLog文件路径

Liquibase学习1 - 安装、简单使用相关推荐

  1. 小程序源码:云开发表情包制作神器-多玩法安装简单

    该款小程序是一个表情包制作 内容毕竟丰富,另外自定义制作方面也是特别的自由 支持自主上传图片,自定义文章,另外拥有多种素材模板以供选择 这是一款云开发的小程序,但是安装还是挺简单的 搭建教程: 首先使 ...

  2. 小程序源码:宝宝起名神器微信小程序源码下载-多玩法安装简单

    这款小程序支持输入姓氏自动起名,不满意还可以点击换一换来找到满意的 支持起两个字或者三个字的名字 另外小编也给该款小程序添加了几个流量给大家 下面就来看看小编的测试演示图吧! 小程序源码下载地址:小程 ...

  3. 040-云E办_学习和安装FastDFS以及安装Nginx

    040-云E办_学习和安装FastDFS以及安装Nginx 一.简介: 1.介绍: 2.架构图: 3.上传流程: 4.下载流程: 5.专业术语: 6.同步机制 7.同类产品简单对比 二.安装FastD ...

  4. 小程序源码:全新实用工具证件照制作-多玩法安装简单

    这是一款证件照制作的微信小程序,里面也支持直接微信公众号版本生成安装 支持多种尺寸制作 支持相册上传于直接相机拍摄 支持多种类型的证件制作如,职业证件,公务员证件,身份证等各种类型 支持电子照存档等等 ...

  5. 小程序源码:全新动态视频壁纸-多玩法安装简单

    这是一款主打动态视频壁纸的一款微信小程序源码 当然啦,里面也是有静态壁纸的 其实这款小程序也可以说是短视频小程序都可以 该款小程序全采集,另外支持多种流量主 大家应该知道小编之前也发过一款动态壁纸的小 ...

  6. 小程序源码:王者荣耀改重复名,空白名最低战力查询助手-多玩法安装简单

    这是一款由重复名,空白名.和各区战力查询组合的一款微信小程序源码! 重复名支持一键生成几十个,就再也不怕都被别人用过了! 空白名支持多种空白名,王者荣耀空白名,贵族居中空白名,QQ微信专属空白名 战力 ...

  7. 小程序源码:喝酒娱乐小游戏助力神器-多玩法安装简单

    大家好今天给大家带来另外一款喝酒小神器 好像记得小编之前也发过好几款这种小程序源码吧 但是每一款的UI或者功能什么的都还是会有所不一样的 大家也可以找找之前所发的那几款对比一下然后决定自己需要哪一款哟 ...

  8. 小程序源码:uni-app云开发的网盘助手-多玩法安装简单

    这是一款uni-app开发的一款网盘小助手小程序源码 该源码主要用于用户输入关键词然后全网抓取百度网盘资源内容 另外呢该小程序还可以免费领取百度网盘七天会员,所以用来引流特别的不错 该小程序还有外卖系 ...

  9. 小程序源码:王者战力查询,游戏扫码登录,王者巅峰信息查询等等支持流量主收益和CPS收益-多玩法安装简单

    这是一款特别强大的一款微信小程序源码 初步算了一下,该款小程序目前包含了几十个功能 具体功能如以下: 游戏扫码登录 王者战力查询 改名生成(多种生成方式) 头像框制作(N款模板) 王者巅峰数据查询 王 ...

最新文章

  1. 三种基本排序的实现及其效率对比:冒泡排序、选择排序和插入排序
  2. 管理不再是交换,而是相互成全!做到这三点,管理更有成效!
  3. ms sql 主键自动生成32位guid
  4. centOS Redhat yum的配置
  5. 使用Mybatis Generator自动生成代码
  6. AUTHORITY-CHECK常用事务代码
  7. Codeforces Round #401 (Div. 2) D. Cloud of Hashtags
  8. 一次性加载树结构数据表 mapper加载
  9. linux服务器配置python环境_服务器python环境配置福利,CentOS ,Linux 一键下载python3和环境配置...
  10. 蓝牙怎么区分单模和双模_小院闲聊#01#——蓝牙的发展和不同蓝牙之间的关系...
  11. magento url rewrite规则
  12. python画简单图-python绘制简单彩虹图
  13. java 反射创建属性_使用Java反射机制确定基本数据类型属性
  14. ld: warning: cannot find entry symbol _start; defaulting to 00000000080481d8
  15. VTP(VLAN中继协议/虚拟局域网干道协议 VLAN Trunking Protocol)
  16. 超五类屏蔽双绞线和计算机电缆区别,什么是超五类网线?双绞线(网线)常用种类的区别详解...
  17. ✨✨✨【C语言】带你用最短的时间刷题(附解题思路、具体代码)不断更新(二)✨✨✨
  18. tomcat的startup.bat启动成功了,但是页面加载不了
  19. j2ee期末考试总结
  20. FT232RL-REEL全隔离原理图,带I/O保护,防电流倒灌等

热门文章

  1. 黄奕出轨密会富商老公发飙怒骂 前夫补刀:淫猫忘不了偷腥
  2. javascript面试-实现lodash的\_.get
  3. JS全排列的几种算法
  4. python入门项目03:完成黑心资本家发工资的程序
  5. AI时代的数据之争与公共领域界定
  6. 算法面试题:最长回文子串
  7. web版本 开源压测工具_免费压测工具
  8. 数据库(四)—— 数据库设计
  9. vue项目实现打印功能
  10. 在职研究生计算机专业好考么,计算机在职研究生好考吗?