boot-admin整合Liquibase实现数据库版本管理

news2024/12/25 1:09:26

Liquibase 和 Flyway 是两款成熟的、优秀的、开源/商业版的数据库版本管理工具,鉴于 Flyway 的社区版本对 Oracle 数据库支持存在限制,所以 boot-admin 选择整合 Liquibase 提供数据库版本管理能力支持。
Liquibase 开源版使用 Apache 2.0 协议。

Liquibase的适用情形?

  • 在你的项目进行版本升级的时候,大概率情况下数据库也需要同步升级,Liquibase 会自动扫描数据库迁移文件(changeSet),将迁移文件的版本号与历史记录表(changelog )中的版本号进行对比,略过已执行的的迁移文件,顺序执行未执行的新版本迁移文件,最终实现数据库与代码版本相匹配;
  • 当多人协作开发项目的时候,系统源代码可使用 git 保持同步,那么数据库的同步就可交由 liquibase 来保证;
  • 使用 liquibase 可以方便地比较两个数据库的差异;
  • 使用 liquibase 还支持数据库版本回滚。

Liquibase的优点有哪些?

  1. 配置文件支持SQL、XML、JSON 或者 YAML;
  2. 可兼容14种主流数据库如 oracle,mysql 等,支持平滑迁移;
  3. 版本控制按序执行;
  4. 可以用上下文控制sql在何时何地如何执行;
  5. 具备在应用中具有if / then逻辑的能力;
  6. 支持 schema 的变更;
  7. 根据配置文件自动生成sql语句用于预览;
  8. 可重复执行迁移;
  9. 可插件拓展;
  10. 可回滚;
  11. 支持schema方式的多租户(multi-tenant);
  12. 能够在多种数据库类型上具有相同的更改描述;
  13. 生成的数据库历史记录文档;
  14. 能够轻松指定更复杂的多语句更改。

整合要点

boot-admin 是一款采用前后端分离模式、基于 SpringCloud 微服务架构的SaaS后台管理框架。系统内置基础管理、权限管理、运行管理、定义管理、代码生成器和办公管理6个功能模块,集成分布式事务 Seata、工作流引擎 Flowable、业务规则引擎 Drools、后台作业调度框架 Quartz 等,技术栈包括 Mybatis-plus、Redis、Nacos、Seata、Flowable、Drools、Quartz、SpringCloud、Springboot Admin Gateway、Liquibase、jwt、Openfeign、I18n等。

项目源码仓库github
项目源码仓库gitee

引入Maven依赖

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

添加配置

spring:
  liquibase:
    enabled: true
    change-log: classpath:liquibase/master.xml

创建master.xml

在 resources 下创建文件夹 liquibase ,创建文件 master.xml

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

    <includeAll path="liquibase/changelogs/" relativeToChangelogFile="false"/>

</databaseChangeLog>

在 liquibase 文件夹下创建 changelogs 和 sql 两个文件夹,如下图所示:
在这里插入图片描述

编写数据库变更单元 changeSet

在 resources\liquibase\changelogs 下创建 changeSet 文件,推荐每月一个 xml 文件,文件名格式:【changelog-年度+月份.xml】,如:changelog-202304.xml
常用操作举例:

创建表

    <changeSet author="admin (generated)" id="00001-9">
        <createTable remarks="行政区划表" tableName="TB_ADM_DIV">
            <column name="GUID" remarks="主键" type="NVARCHAR2(38)">
                <constraints nullable="false" primaryKey="true" primaryKeyName="PK_TB_ADM_DIV"/>
            </column>
            <column name="ADM_DIV_CODE" remarks="行政区划代码" type="NVARCHAR2(12)">
                <constraints nullable="false"/>
            </column>
            <column name="ADM_DIV_NAME" remarks="行政区划名称" type="NVARCHAR2(100)">
                <constraints nullable="false"/>
            </column>
            <column name="CREATE_BY" remarks="记录创建者" type="NVARCHAR2(100)">
                <constraints nullable="false"/>
            </column>
            <column name="CREATE_TIME" remarks="记录创建时间" type="${type.datetime}">
                <constraints nullable="false"/>
            </column>
            <column name="MODIFY_BY" remarks="记录最后修改者" type="NVARCHAR2(100)">
                <constraints nullable="false"/>
            </column>
            <column name="MODIFY_TIME" remarks="记录最后修改时间" type="${type.datetime}">
                <constraints nullable="false"/>
            </column>
            <column defaultValueComputed="${now}" name="DATESTAMP" remarks="时间戳" type="${type.datetime}">
                <constraints nullable="false"/>
            </column>
            <column name="ENABLED" remarks="启用状态;ENABLED" type="NVARCHAR2(1)">
                <constraints nullable="false"/>
            </column>
            <column name="DELETED" remarks="删除状态;DELETED" type="NVARCHAR2(1)">
                <constraints nullable="false"/>
            </column>
            <column name="VERSION" remarks="乐观锁" type="${type.int}">
                <constraints nullable="false"/>
            </column>
            <column name="REMARKS" remarks="备注" type="NVARCHAR2(900)"/>
            <column name="TENANT_ID_" remarks="租户ID" type="NVARCHAR2(38)">
                <constraints nullable="false"/>
            </column>
            <column name="PARENT_GUID" remarks="父级GUID" type="NVARCHAR2(38)">
                <constraints nullable="false"/>
            </column>
            <column name="LEAF" remarks="是否末级;YESNO" type="NVARCHAR2(1)">
                <constraints nullable="false"/>
            </column>
            <column name="SORT" remarks="顺序号" type="${type.int}">
                <constraints nullable="false"/>
            </column>
        </createTable>
    </changeSet>

添加表字段

    <changeSet author="admin" id="00002-1">
        <addColumn tableName="TB_ADM_DIV">
            <column name="EXT" remarks="扩展" type="VARCHAR(64)"/>
        </addColumn>
    </changeSet>

删除表字段

    <changeSet author="admin" id="00002-2">
        <dropColumn tableName="TB_ADM_DIV" columnName="EXT"/>
    </changeSet>

修改表字段说明

    <changeSet author="admin" id="00002-3">
        <setColumnRemarks tableName="TB_ADM_DIV" columnName="EXT" remarks="扩展字段"/>
    </changeSet>

修改表字段类型

    <changeSet author="admin" id="00002-4">
        <modifyDataType tableName="TB_ADM_DIV" columnName="EXT" newDataType="VARCHAR2(2000)"/>
    </changeSet>

创建视图

    <changeSet author="admin (generated)" id="00001-1" dbms="oracle">
        <createView fullDefinition="true" remarks="表和视图" viewName="V_TABLES_MASTER">
            CREATE OR REPLACE FORCE VIEW V_TABLES_MASTER (TABLE_SCHEMA, TABLENAME, TABLETYPE, COMMENTS, TENANT_ID_) AS
            select SYS_CONTEXT('USERENV','CURRENT_SCHEMA') TABLE_SCHEMA,
            t.tname tableName,
            tabtype tabletype,
            f.comments comments,
            'DEMO' TENANT_ID_
            from tab t
            inner join user_tab_comments f
            on t.tname = f.table_name
            where tname != 'DATABASECHANGELOG'
            and tname != 'DATABASECHANGELOGLOCK'
            and tname != 'UNDO_LOG'
        </createView>
    </changeSet>
    <changeSet author="37514 (generated)" id="00000-2" dbms="mysql">
        <createView fullDefinition="true" remarks="表和视图" viewName="V_TABLES_MASTER">
            CREATE OR REPLACE VIEW V_TABLES_MASTER  AS
            SELECT
            TABLE_SCHEMA,
            TABLE_NAME AS TABLENAME,
            case when table_type='BASE TABLE' then 'TABLE' ELSE table_type END AS TABLETYPE,
            TABLE_COMMENT AS COMMENTS,
            'DEMO' TENANT_ID_
            FROM
            information_schema.`TABLES`
            WHERE table_name != 'databasechangeloglock' AND TABLE_NAME != 'databasechangelog' AND TABLE_NAME != 'undo_log'
        </createView>
    </changeSet>

兼容 Oracle 和 Mysql 配置

    <property name="type.datetime" value="date" dbms="oracle"/>
    <property name="type.datetime" value="timestamp" dbms="mysql"/>
    <property name="type.int" value="NUMBER(*, 0)" dbms="oracle"/>
    <property name="type.int" value="INT" dbms="mysql"/>
    <property name="type.decimal" value="NUMBER(*, 2)" dbms="oracle"/>
    <property name="type.decimal" value="DECIMAL" dbms="mysql"/>
    <property name="now" value="SYSDATE" dbms="oracle"/>
    <property name="now" value="now()" dbms="mysql,h2"/>
    <property name="autoIncrement" value="true" dbms="mysql,h2,postgresql,oracle"/>
    <property name="amount" value="decimal(20,2)"/>
    <property name="uuid" value="sys_guid()" dbms="oracle"/>
    <property name="uuid" value="UUID()" dbms="mysql"/>

执行 SQL 文件

    <changeSet id="20000820-003" author="Administrator" dbms="oracle">
        <sqlFile dbms="oracle" path="classpath:/liquibase/sql/seata-undo_log-oracle.sql" />
    </changeSet>
    <changeSet id="20000820-003" author="Administrator" dbms="mysql">
        <sqlFile dbms="mysql" path="classpath:/liquibase/sql/seata-undo_log-mysql.sql" />
    </changeSet>

需将对应 sql 文件放在指定文件夹中。

Liquibase changeSet常用命令清单

add

标签描述
addAutoIncrement将一个已存在的列转换为自增
addColunm增加列
addDefaultValue对已存在的列增加默认值
addForeignKeyConstraint对已存在的列增加外键约束
addLookupTable创建外键关联的表
addNotNullConstraint对已存在的列增加非空约束
addPrimaryKey对已存在的列增加主键约束
ddUniqueConstraint对已存在的列增加主键约束

create

标签描述
createIndex创建索引
createProcedure创建存储过程
createSequence创建序列
createTable创建表
createView创建视图

drop

标签描述
dropAllForeignKeyConstraints删除全部的外键约束
dropColumn删除列
dropDefaultValue删除默认值设置
dropForeignKeyConstraint删除某一列的外键约束
dropNotNullConstraint删除非空约束
dropIndex删除索引
dropSequence删除约束
dropProcedure删除存储过程
dropPrimaryKey删除主键
dropTable删除表
dropUniqueConstraint删除唯一性约束
dropView删除视图

rename

标签描述
renameColumn重命名列
renameSequence重命名序列
renameTable重命名表
renameView重命名视图

sql

标签描述
sql原生SQL
sqlFile引入 SQL 文件

other

标签描述标签描述
alterSequence修改序列customChange自定义change类型,需要自己实现liquibase.change.custom.CustomSqlChange、liquibase.change.custom.CustomTaskChange接口
delete删除数据empty空操作
executeCommand执行系统命令,如 mysqldumpinsert插入数据
loadData加载 csv 文件到已存在的表中loadUpdateData加载 csv 文件到已存在的表中,但是会判断是否存在,存在更新,否则新增
mergeColumns将两列值合并在一起,存入新列中modifyDataType修改列数据类型
output记录一条消息并继续执行setColumnRemarks列上添加备注
setTableRemarks表上添加备注stop通过消息停止 Liquibase
tagDatabase将标签应用于数据库以供将来回滚update更新数据

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/493178.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

实现服务器版本---表白墙(Servlet)

目录 一、创建Servlet项目 二、约定前后端交互接口 三、前端代码 四、后端代码 五、效果演示 结合Servlet API &#xff0c;实现一个服务器版本表白墙。实现的这个表白墙&#xff0c;就通过服务器来保存这里的消息数据&#xff0c;进而做到 “持久化” 存储。 一、创建Se…

浮点数中的阶码和尾数

阶码和尾数 阶码尾数浮点数浮点数表示示例 例题分析总结 阶码 在机器中表示一个浮点数时需要给出指数&#xff0c;这个指数用整数形式表示&#xff0c;这个整数叫做阶码。 尾数 常用对数的小数部分&#xff0c;用于科学计数法&#xff0c;其表示方法为:Mantissa x Base^Expo…

k210单片机的串口交互实验

先来看看实验的结果吧&#xff0c;k210的9口为RX&#xff0c;10口为TX。接线&#xff1a; 9口接usb转ttl的TX 10口接usb转ttl的RX 下面介绍一下k210需要使用的模块&#xff1a; K210 一共有 3 个串口&#xff0c;每个串口可以自由映射引脚。 例&#xff1a; # IO10→RX1&#…

JuiceFS__持久化缓存源码走读

JuiceFS__持久化缓存源码走读 JuiceFS 是一款高性能 POSIX 文件系统&#xff0c;针对云原生环境特别优化设计&#xff0c;在 Apache 2.0 开源协议下发布。使用 JuiceFS 存储数据&#xff0c;数据本身会被持久化在对象存储&#xff08;例如 Amazon S3&#xff09;&#xff0c;而…

java小记 2023-05-05

public class Test {/*** 谓类的方法就是指类中用static 修饰的方法&#xff08;非static 为实例方法&#xff09;&#xff0c;比如main 方法&#xff0c;那么可以以main* 方法为例&#xff0c;可直接调用其他类方法&#xff0c;必须通过实例调用实例方法&#xff0c;this 关键…

7.3 有源滤波电路(2)

四、开关电容滤波器 开关电容电路由受时钟脉冲信号控制的模拟开关、电容器和运算放大电路三部分组成。这种电路的特性与电容器的精度无关&#xff0c;而仅与各电容器电容量之比的准确性有关。在集成电路中&#xff0c;可以通过均匀地控制硅片上氧化层的介电常数及其厚度&#…

国产版ChatGPT大盘点

我们看到,最近,国内大厂开始密集发布类ChatGPT产品。 一方面,是因为这是最近10年最大的趋势和机会。 另一方面,国内的AI,不能别国外卡了脖子。 那在类ChatGPT赛道上,哪些中国版的ChatGPT能快速顶上?都各有哪些困境需要突破呢?本文给诸位带来各个玩家的最新进展。 *…

大数据Doris(十二):Unique数据模型

文章目录 Unique数据模型 一、读时合并 二、写时合并 Unique数据模型 在某些多维分析场景下,用户更关注的是如何保证 Key 的唯一性,即如何获得 Primary Key 唯一性约束。因此,我们引入了 Unique 数据模型,该模型可以根据相同的Primary Key 来保留后插入的数据,确保数据…

Day962.如何更好地重构和组织后端代码 -遗留系统现代化实战

如何更好地重构和组织后端代码 Hi&#xff0c;我是阿昌&#xff0c;今天学习记录是关于如何更好地重构和组织后端代码的内容。 如果说在气泡上下文中开发新的需求&#xff0c;类似于老城区旁边建设一个新城区&#xff0c;那么在遗留系统中开发新的需求&#xff0c;就类似于在…

c++的构造函数与析构函数

构造函数是一种特殊的成员函数&#xff0c;用于在对象创建时初始化对象的成员变量。它的名称与类名相同&#xff0c;没有返回类型&#xff0c;可以有参数。当创建对象时&#xff0c;构造函数会自动调用&#xff0c;以初始化对象的成员变量。如果没有定义构造函数&#xff0c;编…

华为OD机试真题-24点运算【2023】【JAVA】

一、题目描述 计算24点是一种扑克牌益智游戏&#xff0c;随机抽出4张扑克牌&#xff0c;通过加()&#xff0c;减(-)&#xff0c;乘(*), 除(/)四种运算法则计算得到整数24&#xff0c;本问题中&#xff0c;扑克牌通过如下字符或者字符串表示&#xff0c;其中&#xff0c;小写jo…

PCL1.12.0+Vtk7.1.1安装

1. qt4&#xff1a;Ubuntu 20.04 LTS 安装qt4 library_ubuntu20.04安装qt4 2.本文下载过程可参考1&#xff1a;ubuntu20.04下安装pcl_ubuntu安装pcl_Yuannau_jk的博客-CSDN博客 参考2&#xff1a;Ubuntu 20.04.05安装PCL-1.12.0_no package metslib found_zhiTjun的博客-CSDN…

解决 IDEA中的Tomcat服务器控制台乱码

解决 IDEA中的Tomcat服务器控制台乱码 问题描述&#xff1a;当我们使用idea编辑器部署web程序到tomcat服务器上&#xff0c;当我们运行tomcat的时候控制台出现服务器输出内容乱码的情况&#xff0c;这个问题可能是由于编码不一致引起的。在IDEA中&#xff0c;如果项目的编码方…

HttpServletRequest在Spring中的获取和注入 @Autowired注入Request

问题描述&#xff1a; 在最近一次团队review代码时&#xff0c;团队成员发现有将HttpServletRequest 直接通过Autowired注入的情况&#xff0c;于是大家产生了一个疑问&#xff0c;HttpServletRequest并非Spring中的类&#xff0c;且在没有手动通过Bean的方式注入&#xff0c;…

Oracle数据库、实例、用户、表空间、表之间的关系

数据库&#xff1a; Oracle数据库是数据的物理存储。这就包括&#xff08;数据文件ORA或者DBF、控制文件、联机日志、参数文件&#xff09;。其实Oracle数据库的概念和其它数据库不一样&#xff0c;这里的数据库是一个操作系统只有一个库。可以看作是Oracle就只有一个大数据库。…

Vue核心 绑定样式 条件渲染

1.11.绑定样式 class样式&#xff1a; 写法&#xff1a;:class“xxx”&#xff0c;xxx 可以是字符串、数组、对象:style“[a,b]” 其中a、b是样式对象**:style“{fontSize: xxx}”**其中 xxx 是动态值 字符串写法适用于&#xff1a;类名不确定&#xff0c;要动态获取数组写法…

HTB靶机07-Cronos-WP

cronos IP&#xff1a;10.10.10.13 scan ┌──(xavier㉿kali)-[~] └─$ sudo nmap -sSV -T4 10.10.10.13 Starting Nmap 7.93 ( https://nmap.org ) at 2023-04-06 23:19 CST Nmap scan report for 10.10.10.13 Host is up (0.23s latency). Not shown: 997 closed tcp por…

SpringCloud全面学习笔记之进阶篇

目录 前言微服务保护初识Sentinel雪崩问题及解决方案雪崩问题超时处理仓壁模式熔断降级流量控制总结 服务保护技术对比Sentinel介绍和安装微服务整合Sentinel 流量控制快速入门流控模式关联模式链路模式小结 流控效果warm up排队等待 热点参数限流全局参数限流热点参数限流案例…

算法记录 | Day52 动态规划

300.最长递增子序列 思路&#xff1a; 1.dp[i]的定义:以 nums[i] 结尾的最长递增子序列长度。 2.状态转移方程:位置i的最长升序子序列等于j从0到i-1各个位置的最长升序子序列 1 的最大值。 if (nums[i] > nums[j]) dp[i] max(dp[i], dp[j] 1); 注意这里不是要dp[i] …

基于AT89C52单片机的电子秒表设计与仿真

点击链接获取Keil源码与Project Backups仿真图&#xff1a; https://download.csdn.net/download/qq_64505944/87755619?spm1001.2014.3001.5503 源码获取 主要内容&#xff1a; 本设计以AT89C52单片机为核心&#xff0c;采用常用电子器件设计&#xff0c;包括电源开关、按键…