SpringBoot项目使用Liquibase 数据库版本管理

数据库版本管理


一、概述

Liquibase 是一个用于数据库重构、变更管理和版本控制的开源工具。它通过对数据库变更进行版本化管理,支持多人协作开发、多分支合并,并提供多种数据库类型的支持。

二、特点

  • 多数据库支持:MySQL、PostgreSQL、Oracle、SQL Server、DB2、H2等
  • 多格式变更日志:XML、YAML、JSON、SQL
  • 上下文执行逻辑:支持按需运行特定上下文变更
  • 集群安全更新:确保分布式环境下的数据库更新安全
  • 变更文档生成:自动生成数据库修改文档(HTML格式)
  • 数据库对比:使用命令对比两个数据库结构差异
  • 多平台集成:支持命令行、Ant、Maven及应用程序内嵌

三、集成步骤

1. 添加依赖

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

2. 创建目录结构

在项目 resources 目录下创建 liquibase 目录用于存放 liquibase 相关的配置文件,在 liquibase 目录下创建 changelog 目录存放所有 changelog 文件

src/main/resources/
    └── liquibase/
        ├── master.xml
        └── changelog/
            ├── common/
            │   ├── master.xml
            │   └── 20230110_common_init_table.sql
            └── other_module/

3.创建master.xml文件

liquibase 目录下的 master.xml 为 liquibase 的入口,通过 include 标签将其它的 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"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
            http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd">

    <!--
    1:includeAll 标签可以把一个文件夹下的所有 changelog 都加载进来。如果单个加载可以用 include。
    2:includeAll 标签里有两个属性:path 和 relativeToChangelogFile。
        2.1:path (在 include 标签里是 file):指定要加载的文件或文件夹位置
        2.2:relativeToChangelogFile :文件位置的路径是否相对于 root changelog 是相对路径,默认 false,即相对于 classpath 是相对路径。
    -->

   <include file="liquibase/changelogs/common/master.xml"/>

</databaseChangeLog>

具体模块的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"
        xsi:schemaLocation="http://www.liquibase.org/xml/ns/dbchangelog
            http://www.liquibase.org/xml/ns/dbchangelog/dbchangelog-3.4.xsd">

    <!--
    1:includeAll 标签可以把一个文件夹下的所有 changelog 都加载进来。如果单个加载可以用 include。
    2:includeAll 标签里有两个属性:path 和 relativeToChangelogFile。
        2.1:path (在 include 标签里是 file):指定要加载的文件或文件夹位置
        2.2:relativeToChangelogFile :文件位置的路径是否相对于 root changelog 是相对路径,默认 false,即相对于 classpath 是相对路径。
    -->

   <changeSet id="liquibase/20230110_common_init_table.sql" author="xxxx">
        <sqlFile path="liquibase/20230110_common_init_table.sql"/>
    </changeSet>

</databaseChangeLog>

id:执行id,执行文件名称

4. 应用配置

指定 liquibase 的 changelog文件

spring:
  liquibase:
    enabled: false # 是否启用
    change-log: classpath:/liquibase/master.xml 

四、如何 让Liquibase 知道这个变更集,跳过

核心原理是:Liquibase 通过在数据库中维护一个名为 DATABASECHANGELOG 的表来记录所有已经执行过的变更集。你需要手动在这个表中插入一条记录,让它认为这个脚本已经成功执行了。

INSERT INTO DATABASECHANGELOG (
    ID, AUTHOR, FILENAME, DATEEXECUTED, ORDEREXECUTED, 
    EXECTYPE, MD5SUM, DESCRIPTION, COMMENTS, LIQUIBASE
)
SELECT 
    'liquibase/data/changelog-test-0.0.3', -- 与 changelog 文件中的 id 属性对应
    'name', -- 与 changelog 文件中的 author 属性对应
    'liquibase/data/master.xml',  -- 注意:这个路径必须与之后Liquibase变更集中指定的路径完全一致
    NOW(), -- 变更集被执行的时间戳
    max_order + 1, -- 一个从 1 开始自增的数字,表示该变更集在本次执行中的顺序
    'EXECUTED', -- 执行类型
    NULL, -- 将MD5SUM设置为NULL,让Liquibase自己计算并更新
    'sqlFile path=liquibase/data/changelog-test-0.0.3.sql',
    '',
    '4.23.0'
FROM (SELECT COALESCE(MAX(ORDEREXECUTED), 0) as max_order FROM DATABASECHANGELOG) as tmp;

五、changelog文件命名规则

文件名称:日期_说明_data/table.xml

六、注意事项

1.初始化顺序问题

问题描述:

@PostConstruct注解的方法会在Liquibase之前执行,如果这些方法需要访问数据库,会导致错误。

解决方案:

使用CommandLineRunner或ApplicationRunner接口替代@PostConstruct

2.约定

  • 项目采用Liquibase进行数据库操作管理,但不限制本地测试数据。仅要求必要的操作记录到日志文件。
  • DDL语句必须在DML语句之前执行,可通过文件引入顺序来决定执行顺序
  • 语句必须以;号收尾
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值