boot-admin整合Liquibase实现数据库版本管理
Liquibase 和 Flyway 是两款成熟的、优秀的、开源/商业版的数据库版本管理工具,鉴于 Flyway 的社区版本对 Oracle 数据库支持存在限制,所以 boot-admin 选择整合 Liquibase 提供数据库版本管理能力支持。
Liquibase 开源版使用 Apache 2.0 协议。
Liquibase的适用情形?
- 在你的项目进行版本升级的时候,大概率情况下数据库也需要同步升级,Liquibase 会自动扫描数据库迁移文件(changeSet),将迁移文件的版本号与历史记录表(changelog )中的版本号进行对比,略过已执行的的迁移文件,顺序执行未执行的新版本迁移文件,最终实现数据库与代码版本相匹配;
- 当多人协作开发项目的时候,系统源代码可使用 git 保持同步,那么数据库的同步就可交由 liquibase 来保证;
- 使用 liquibase 可以方便地比较两个数据库的差异;
- 使用 liquibase 还支持数据库版本回滚。
Liquibase的优点有哪些?
- 配置文件支持SQL、XML、JSON 或者 YAML;
- 可兼容14种主流数据库如 oracle,mysql 等,支持平滑迁移;
- 版本控制按序执行;
- 可以用上下文控制sql在何时何地如何执行;
- 具备在应用中具有if / then逻辑的能力;
- 支持 schema 的变更;
- 根据配置文件自动生成sql语句用于预览;
- 可重复执行迁移;
- 可插件拓展;
- 可回滚;
- 支持schema方式的多租户(multi-tenant);
- 能够在多种数据库类型上具有相同的更改描述;
- 生成的数据库历史记录文档;
- 能够轻松指定更复杂的多语句更改。
整合要点
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等。
引入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 文件 |
othr
| 标签 | 描述 | 标签 | 描述 |
|---|---|---|---|
| alterSequence | 修改序列 | customChange | 自定义change类型,需要自己实现liquibase.change.custom.CustomSqlChange、liquibase.change.custom.CustomTaskChange接口 |
| delete | 删除数据 | empty | 空操作 |
| executeCommand | 执行系统命令,如 mysqldump | insert | 插入数据 |
| loadData | 加载 csv 文件到已存在的表中 | loadUpdateData | 加载 csv 文件到已存在的表中,但是会判断是否存在,存在更新,否则新增 |
| mergeColumns | 将两列值合并在一起,存入新列中 | modifyDataType | 修改列数据类型 |
| output | 记录一条消息并继续执行 | setColumnRemarks | 列上添加备注 |
| setTableRemarks | 表上添加备注 | stop | 通过消息停止 Liquibase |
| tagDatabase | 将标签应用于数据库以供将来回滚 | update | 更新数据 |
boot-admin整合Liquibase实现数据库版本管理的更多相关文章
- Spring Boot admin 2.0 详解
一.什么是Spring Boot Admin ? Spring Boot Admin是一个开源社区项目,用于管理和监控SpringBoot应用程序. 应用程序作为Spring Boot Admin C ...
- Spring Boot Admin 2.1.0 全攻略
转载请标明出处: https://www.fangzhipeng.com 本文出自方志朋的博客 Spring Boot Admin简介 Spring Boot Admin是一个开源社区项目,用于管理和 ...
- Spring Boot:整合MyBatis框架
综合概述 MyBatis 是一款优秀的持久层框架,它支持定制化 SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集.MyBatis 可以使用简单 ...
- Spring Boot:整合Shiro权限框架
综合概述 Shiro是Apache旗下的一个开源项目,它是一个非常易用的安全框架,提供了包括认证.授权.加密.会话管理等功能,与Spring Security一样属基于权限的安全框架,但是与Sprin ...
- Spring Boot Admin 2.1.0
原文:https://blog.csdn.net/forezp/article/details/86105850 Spring Boot Admin简介 Spring Boot Admin是一个开源社 ...
- 使用 Liquibase 管理数据库版本 - SpringBoot 2.7 .2 实战基础
优雅哥 SpringBoot 2.7 .2 实战基础 - 05 -使用 Liquibase 管理数据库版本 在企业开发中,数据库版本管理好像是一个伪命题,大多项目都是通过 Power Designer ...
- Spring Boot Security 整合 JWT 实现 无状态的分布式API接口
简介 JSON Web Token(缩写 JWT)是目前最流行的跨域认证解决方案.JSON Web Token 入门教程 - 阮一峰,这篇文章可以帮你了解JWT的概念.本文重点讲解Spring Boo ...
- SpringCloud(8)微服务监控Spring Boot Admin
1.简介 Spring Boot Admin 是一个管理和监控Spring Boot 应用程序的开源软件.Spring Boot Admin 分为 Server 端和 Client 端,Spring ...
- Spring boot Mybatis 整合(完整版)
个人开源项目 springboot+mybatis+thymeleaf+docker构建的个人站点开源项目(集成了个人主页.个人作品.个人博客) 朋友自制的springboot接口文档组件swagge ...
- 基于spring boot admin 做监控的一些问题记录
问题一 各个健康节点权限问题 解决方式 加入权限模块 <dependency> <groupId>org.springframework.boot</groupId> ...
随机推荐
- 切片slice
1.切片 切片是数组的一个引用,因此切片是引用类型,在进行传递时,遵守引用类型的机制 切片的使用和数组类似,如遍历切片,访问切片的元素和求切片长度len(slice)都一样. 切片的长度是可以变化的, ...
- java锁之初相见
废话不多说,先上锁的分类图 1.乐观锁&悲观锁 悲观锁 悲观锁认为自己在使用数据的时候一定有别的线程来修改数据,因此在获取数据的时候会先加锁,把别的线程阻塞住,最终确保数据不会被别的线程修改. ...
- python之pyqt5-第一个pyqt5程序-图像压缩工具(2.0版本)-小记
(如想转载,请联系博主或贴上本博地址) 此篇为上一篇pyqt5图像压缩小工具改良版.因为比较简单,下面直接贴上代码. 效果图: # -*- coding: utf-8 -*- # Form imple ...
- windows下使用Wireshark调试chrome浏览器的HTTP/2流量
1.在Wireshark官网(https://www.wireshark.org/#download)下载对应的Wireshark安装包,进行安装 2.增加系统环境变量设置(计算机 -- 右键 -- ...
- 取出预训练模型中间层的输出(pytorch)
1 遍历子模块直接提取 对于简单的模型,可以采用直接遍历子模块的方法,取出相应name模块的输出,不对模型做任何改动.该方法的缺点在于,只能得到其子模块的输出,而对于使用nn.Sequensial() ...
- URule规则引擎
没有规则,不成方圆: 一.背景 前段时间,在做项目重构的时候,遇到很多地方需要做很多的条件判断.当然可以用很多的if-else判断去解决,但是当时也不清楚怎么回事,就想玩点别的.于是乎,就去调研了规则 ...
- TSCTF-J 2022 WP
Re baby_xor 加密逻辑如上,密文动态调试,然后 Shift+E 导出密文[这样避免了手动获取] # encoding=utf-8 enc=[ 0x12, 0x00, 0x00, 0x00, ...
- 基于Pierre Dellacherie的俄罗斯方块-05Pierre Dellacherie算法
基于Pierre Dellacherie的俄罗斯方块-05Pierre Dellacherie算法 Pierre Dellacherie算法感觉上像是一个遍历算法,给与各个参数不同的权重,使得更加合理 ...
- 从零开始学习Java系列之Java运行机制与跨平台特性
全文大约[4000]字,不说废话,只讲可以让你学到技术.明白原理的纯干货!并带有丰富的案例及配图,让你更好地理解和运用文中的技术概念,给你带来具有足够启迪的思考-- 在上一篇文章中,壹哥给大家介绍了J ...
- deepin安装retropie
deepin安装retropie,并解决游戏列表中文乱码已经retroarch中文乱码. 安装retropie模拟器 sudo apt install -y git dialog unzip xmls ...