spring boot整合flyway实现数据的动态维护
1、简单介绍一下flyway
Flyway 是一款开源的数据库版本控制工具,主要用于管理数据库结构的变更(如创建表、修改字段、插入数据等)。它通过跟踪和执行版本化的迁移脚本,帮助团队实现数据库变更的自动化。接下来简单介绍一下flyway的工作流程:
1.1、 初始化阶段
-
检查元数据表
Flyway 首先检查目标数据库中是否存在flyway_schema_history
表(默认表名称,也可以自定义历史表名称)。-
不存在:自动创建该表,用于记录迁移历史
-
已存在:读取已有迁移记录
-
千万不要手动的修改历史表的任何数据,不然肯定会导致版本管理错误。
1.2、 迁移扫描
-
脚本加载
扫描配置的locations
路径(默认classpath:db/migration
),识别两类脚本:-
版本化迁移脚本(
V
开头) -
可重复迁移脚本(
R
开头)
-
1.3、校验阶段
-
校验 Checksum
对比已执行脚本的checksum
与本地文件的checksum
:-
若已执行脚本的 checksum 发生变化 → 抛出错误(防止篡改历史脚本)
-
校验通过 → 进入迁移阶段
-
1.4、 迁移执行
-
版本化迁移
按版本号顺序执行所有 未应用 的V
前缀脚本,且 仅执行一次 -
可重复迁移
按文件名顺序执行R
前缀脚本,当脚本内容变化时 重新执行
1.5、 更新元数据
每个成功执行的脚本会被记录到 flyway_schema_history
表,包含:
版本号
脚本名称
checksum
执行时间
执行状态
如图就是一个默认的历史表中数据。
在这里详细解释一个flyway中的两种字母开头的执行脚本的不同;
V
开头 vs R
开头脚本的区别
1. 版本化迁移脚本(V
前缀)
-
命名规则
V<Version>__<Description>.sql
(例如V1.2__Create_User_Table.sql
)-
Version
:唯一且不可变的版本号(建议使用语义化版本,如1.0.1
) -
Description
:人类可读的描述(使用下划线分隔单词)
-
-
核心特性
-
一次性执行:每个脚本仅执行一次
-
顺序敏感:按版本号顺序依次执行
-
内容不可变:已执行的脚本内容不可修改(否则校验失败)
-
-
典型场景
-
创建/修改表结构
-
新增索引或约束
-
一次性数据迁移(如初始化基础数据)
-
2. 可重复迁移脚本(R
前缀)
-
命名规则
R__<Description>.sql
(例如R__Update_Product_View.sql
)-
没有版本号
-
Description
:描述脚本作用(按字母顺序排序执行)
-
-
核心特性
-
重复执行:脚本内容变化时自动重新执行
-
顺序依赖:按文件名字母顺序执行
-
内容可变:允许修改后重新应用
-
-
典型场景
-
维护视图(View)或存储过程(Stored Procedure)
-
更新静态数据(如多环境差异化配置)
-
重建索引或物化视图
-
关键对比总结
特性 | V 前缀脚本 | R 前缀脚本 |
---|---|---|
执行次数 | 仅一次 | 内容变化时重复执行 |
版本号 | 必须唯一且递增 | 无版本号 |
内容修改 | 禁止修改(会导致校验失败) | 允许修改(触发重新执行) |
执行顺序 | 按版本号顺序 | 按文件名字母顺序 |
适用场景 | 结构变更、一次性操作 | 可重复逻辑、数据维护 |
最佳实践建议
-
版本化脚本 (
V
)-
使用语义化版本(如
V1.2.3
) -
每个脚本完成一个独立的变更任务
-
禁止修改已提交到代码仓库的
V
脚本
-
-
可重复脚本 (
R
)-
用于维护视图、存储过程等易变对象
-
通过文件名控制执行顺序(如
R__01_ViewA.sql
,R__02_ViewB.sql
) -
谨慎修改生产环境的
R
脚本(可能触发全量更新)
-
-
混合使用策略
-
用
V
脚本管理表结构变更 -
用
R
脚本管理视图和存储过程
-
示例:
db/migration/
├── V1.0__Create_Tables.sql
├── V1.1__Add_Indexes.sql
└── R__Update_Views.sql
-
校验保护
-
生产环境务必启用
validate-on-migrate: true
-
开发环境可开启
flyway.validate-migration-naming: true
强制命名校验
-
通过合理使用 V
和 R
脚本,可以实现数据库变更的 原子性 和 可追溯性,同时适应不同场景的灵活性需求。
2、使用spring boot项目整合flyway
2.1、新创建一个spring boot项目,并导入一些初始的依赖;
<dependencies><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><dependency><groupId>org.flywaydb</groupId><artifactId>flyway-core</artifactId><!-- 无需指定版本(Spring Boot 已管理) --></dependency><!-- druid连接池 --><dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.18</version></dependency><!-- MySQL--><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId></dependency><!-- 无需指定版本(Spring Boot 已管理) --><dependency><groupId>org.flywaydb</groupId><artifactId>flyway-mysql</artifactId></dependency><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version></dependency></dependencies>
需要注意的一点是,spring官方自动管理的flyway的版本,所以我们只需要指定spring的版本就自动会兼容合适的flyway版本,我的spring boot版本为3.3.9
我们主要使用到的依赖有三个:
flyway-core:flyway的核心依赖
flyway-mysql:指定数据库的类型
mybatis-spring-boot-starter: 数据源的自动配置,也可以是其他的依赖坐标。不一定要是mybatis,如JDBC、JPA等都可以
2.2、配置相应的yml配置文件
spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriver-class-name: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/testflyway?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=UTCusername: rootpassword: 123456flyway:enabled: truelocations: ["classpath:db/migration"] # 修正为数组格式table: flyway_schema_historybaseline-on-migrate: true # 必须启用(处理已有表场景)sql-migration-prefix: "V"sql-migration-separator: "__"sql-migration-suffixes: [".sql"] # 数组格式
logging:level:org.flywaydb: TRACE # 输出最详细日志
我们只需要配置一些flyway的属性,就可以直接使用flyway了。
2.3、编写相应的sql执行语句,并且存放在固定的文件地址
-- 创建用户表
CREATE TABLE IF NOT EXISTS user (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL UNIQUE,email VARCHAR(100) NOT NULL,created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);-- 初始数据插入
INSERT INTO user (username, email) VALUES('admin', 'admin@example.com'),('user1', 'user1@example.com');
我这里就创建了一张数据表,并且插入了一些数据;
将SQL脚本放在合适的位置:
注意SQL脚本的存放位置不是乱放的,要符合我们之前在yml配置文件中书写的配置,SQL脚本的名称也不是随便取得,要符合flyway的命名规范。
2.4、运行spring boot项目
我们配置好了这些之后,就可以直接启动spring boot项目了。如果你是第一次启动项目,flyway会自动扫描相应文件夹下的SQL脚本,并在你的数据库中建立一个历史记录表 flyway_schema_history。要特别注意的是我们千万不要手动的修改这张表中的任何数据,flyway就是根据这张历史记录表来进行SQL脚本的执行等等一系列操作。
我们可以直接在控制台中看到flyway已经顺利的执行我们相应的SQL脚本
我们现在可以连接一下数据库来看看是否正确
可以看到数据库中已经有了相应的数据表,并且数据表中已经有了一些初始数据了
这个是我们第一次启动spring boot项目时自动执行的SQL脚本。那么等我们第二次启动时,flyway还是会扫描相应的SQL脚本,同时查询 flyway_schema_history
历史表,来判断SQL脚本要不要执行。当我们在此运行spring boot项目:
我们在控制台的日志中可以很清楚的看到flyway的执行过程。
3、总结
以上,就是我们使用spring boot整合flyway来进行数据库的版本管理。总体来说是非常简单的,我们只需要一些简单的配置和遵守一些flyway的命名规定就可以直接使用flyway了。这也是spring官方一直在努力推行的
约定大于配置,配置大于编码
当然,flyway的功能还有很多,这篇文章也只是初步帮你认识一下flyway。并且使用spring boot来简单的使用flyway的基本功能,但总的来说,我们几乎可以只通过一些配置文件中属性来使用flyway的绝大部分功能,一下我整理了一些常用的flyway属性,供大家参考:
spring:flyway:# 基础配置enabled: true # 是否启用 Flyway,默认 trueurl: jdbc:mysql://localhost:3306/db # 覆盖默认数据库连接(可选)user: root # 覆盖默认数据库用户(可选)password: root # 覆盖默认数据库密码(可选)# 脚本管理locations: # 迁移脚本路径(默认 classpath:db/migration)- classpath:db/migrations- filesystem:/opt/migrationsencoding: UTF-8 # 脚本文件编码,默认 UTF-8sql-migration-prefix: V # 版本迁移脚本前缀,默认 "V"repeatable-sql-migration-prefix: R # 可重复迁移脚本前缀,默认 "R"sql-migration-separator: __ # 脚本名称分隔符,默认双下划线sql-migration-suffixes: # 脚本后缀列表,默认 [".sql"]- .sql- .pgsql# 迁移规则schemas: public # Flyway 管理的 schema 列表(逗号分隔)table: flyway_history # 元数据表名,默认 "flyway_schema_history"baseline-on-migrate: false # 迁移时自动执行基线(默认 false)baseline-version: 1 # 基线版本号,默认 "1"baseline-description: Initial Setup # 基线描述target: latest # 目标版本(默认最新版本,可用版本号如 "3.1")out-of-order: false # 是否允许乱序执行迁移(默认 false)validate-on-migrate: true # 迁移时校验脚本(默认 true)ignore-missing-migrations: false # 忽略缺失的迁移记录(默认 false)# 占位符配置placeholder-replacement: true # 启用占位符替换(默认 true)placeholders: # 自定义占位符键值对key1: value1key2: value2# 高级配置clean-on-validation-error: false # 校验失败时自动执行 clean(危险!默认 false)connect-retries: 3 # 连接失败重试次数(默认 0)lock-retry-count: 50 # 获取锁的重试次数(默认 50)group: false # 将相同版本的迁移合并为单个事务(默认 false)mixed: false # 是否允许混合 DDL 和 DML(默认 false)skip-default-callbacks: false # 跳过默认回调(默认 false)skip-default-resolvers: false # 跳过默认解析器(默认 false)init-sqls: # 获取连接后立即执行的 SQL 语句- SET ROLE 'myuser'# 多环境配置示例
---
spring:profiles: prodflyway:url: jdbc:mysql://prod-db:3306/prod_dblocations:- "classpath:db/migration/common"- "classpath:db/migration/prod"ignore-migration-patterns: "*:pending"
关键配置说明:
-
基础配置:默认会复用
spring.datasource
配置,需要覆盖时单独指定 -
脚本管理:通过前缀/后缀/路径控制脚本识别规则
-
迁移规则:控制基线、校验、执行顺序等核心行为
-
生产环境注意事项:
-
clean-on-validation-error
应始终保持false
-
out-of-order
需谨慎启用 -
建议明确指定
target
版本控制生产环境迁移
-
-
最佳实践:
-
使用
classpath
和filesystem
组合路径管理脚本 -
通过
placeholders
实现环境差异化配置 -
启用校验确保迁移安全
-
可以通过 flyway.validateMigrationNaming
配置项(默认 false)开启严格的脚本命名校验,建议开发环境开启。
flyway的官网地址为:https://flywaydb.org/
你有如果想了解更多有关flyway的信息,可以直接访问官网
相关文章:

spring boot整合flyway实现数据的动态维护
1、简单介绍一下flyway Flyway 是一款开源的数据库版本控制工具,主要用于管理数据库结构的变更(如创建表、修改字段、插入数据等)。它通过跟踪和执行版本化的迁移脚本,帮助团队实现数据库变更的自动化。接下来简单介绍一下flyway…...

unity中使用spine详解
一.Spine概述 Spine 是一款针对游戏开发的 2D 骨骼动画编辑工具。 Spine 旨在提供更高效和简洁 的工作流程,以创建游戏所需的动画。 Spine原理:将一个模型,根据动画的需求分成一些骨骼,一个骨骼对应一张贴图,控制骨骼…...

14. LangChain项目实战1——基于公司制度RAG回答机器人
教学视频: 12. 基于Gradio搭建基于公司制度RAG_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV11VXRYTErZ/ 环境配置: python版本:3.10.8 服务器:Ubuntu 依赖包requirements.txt文件内容: aiofiles23.2.1 …...

利用STM32TIM自制延迟函数实验
一、实验目的 掌握STM32定时器(TIM)的工作原理及配置方法学习使用HAL库实现微秒级/毫秒级延时函数理解定时器中断服务程序的编写规范 二、实验原理 定时器基础: STM32定时器包含向上计数器、向下计数器、中心对齐模式通过预分频器&#x…...

创建一个MCP服务器,并在Cline中使用,增强自定义功能。
MCP介绍 MCP 是一个开放协议,它标准化了应用程序如何向LLMs提供上下文。可以将 MCP 视为 AI 应用程序的 USB-C 端口。正如 USB-C 提供了一种标准化的方法来将您的设备连接到各种外围设备和配件一样,MCP 提供了一种标准化的方法来将 AI 模型连接到不同的…...
Android Activity栈关系解析
在 Android 系统中,这些类共同构成了 Activity 任务栈管理的核心架构。它们的关系可以类比为一栋大楼的管理体系,每个类负责不同层级的任务。以下是它们的详细解释和实际场景示例: 1. ActivityRecord(活动记录) 是什么…...
java使用word模板填充内容,再生成pdf
1.word模板填充内容 使用EasyPoi写入Word文档。 import cn.afterturn.easypoi.word.WordExportUtil; import org.apache.commons.io.FileUtils; import org.apache.commons.io.IOUtils; import org.apache.poi.xwpf.usermodel.XWPFDocument;import java.io.File; import java…...

回归实战详细代码+解析:预测新冠感染人数
回归实战:预测新冠感染人数 先回顾下回归是个啥玩意 首先需要一组训练集,说人话就是通过一系列x[x1,x2…xn]通过神秘计算得到y的过程,当然人和机器现在都不知道什么计算是什么,这是一个黑箱。 黑箱比喻:把模型想象成自…...

AI人工智能机器学习之聚类分析
1、概要 本篇学习AI人工智能机器学习之聚类分析,以KMeans、AgglomerativeClustering、DBSCAN为例,从代码层面讲述机器学习中的聚类分析。 2、聚类分析 - 简介 聚类分析是一种无监督学习的方法,用于将数据集中的样本划分为不同的组ÿ…...

(下:补充——五个模型的理论基础)深度学习——图像分类篇章
目录 1.1 卷积神经网络基础 3.1 AlexNet网络结构详解与花分类数据集下载 4.1 VGG网络详解及感受野的计算 5.1 GoogLeNet网络详解 6.1 ResNet网络结构,BN以及迁移学习详解 总结(可以直接看总结) 1.1 卷积神经网络基础 视频讲解…...
使用Python自动生成图文并茂的网页分析报告
在数据分析中,不管是市场研究还是科学分析,经常需要使用Python进行数据分析并生成图表报告。一般使用Python生成和展示图表时都是使用matplotlib 库生成静态图片文件,这种方式不便之处是不方便跟动态文字段落结合在一起,也不方便分…...

uniapp-原生android插件开发摘要
uni-app在App侧的原生扩展插件,支持使用java、object-c等原生语言编写,从HBuilderX 3.6起,新增支持了使用uts来开发原生插件。 基础项目 UniPlugin-Hello-AS工程请在App离线SDK中查找 基础项目(App离线SDK)已经配置好了自定义插件所需要的…...

GIT工具学习【1】:基本操作
目录 0.本地代码分区1.配置自己的个人信息(设置一次即可)2.新建仓库3.提交代码到暂存区(加入购物车)4.从暂存区撤回(不会改变工作区文件)5.恢复指定版本(会改变工作区文件)5.1&#…...
《国密算法开发实战:从合规落地到性能优化》
前言 随着信息技术的飞速发展,信息安全已成为全球关注的焦点。在数字化时代,数据的保密性、完整性和可用性直接关系到国家、企业和个人的利益。为了保障信息安全,密码技术作为核心支撑,发挥着至关重要的作用。国密算法,即国家密码算法,是我国自主设计和推广的一系列密码…...

【语法】C++中string类中的两个问题及解答
贴主在学习string类时遇到过两个困扰我的问题,今天拿出来给大家分享一下我是如何解决的 一、扩容时capacity的增长问题 在string的capacity()接口中,调用的是这个string对象的容量(可以存多少个有效字符),而size()是调用的string对象现在有…...
LeetCode-154. 寻找旋转排序数组中的最小值 II
1、题目描述: 已知一个长度为 n 的数组,预先按照升序排列,经由 1 到 n 次 旋转 后,得到输入数组。例如,原数组 nums [0,1,4,4,5,6,7] 在变化后可能得到: 若旋转 4 次,则可以得到 [4,5,6,7,0,…...
2.数据结构:1.Tire 字符串统计
1.Tire 字符串统计 #include<algorithm> #include<cstring> #include<iostream>using namespace std;const int N100010; int son[N][26];//至多 N 层,每一层至多 26 个节点(字母) int cnt[N];//字符串至多 N 个ÿ…...
C语言复习4:有关数组的基础常见算法
# 数组的常见算法 - 查找算法 1. 基本查找/顺序查找 2. 二分查找/折半查找 3. 插值查找 4. 分块查找 5. 哈希查找 6. 树表查找 7. 斐波那契查找 - 排序算法(顾名思义,就是把没有顺序的…...
Ubuntu从零创建Hadoop集群
目录 前言 前提准备 1.设置网关和网段 2.查看虚拟机IP及检查网络 3.Ubuntu相关配置 镜像源配置 下载 vim编辑器 4.设置静态IP和SSH免密(可选) 设置静态IP SSH免密 5.JDK环境部署 6.Hadoop环境部署 7.配置 Hadoop 配置文件 HDFS集群规划 HDFS集群配置 1.配…...

GPIO概念
GPIO通用输入输出口 在芯片内部存在多个GPIO,每个GPIO用于管理多个芯片进行输入,输出工作 引脚电平 0v ~3.3v,部分引脚可容任5v 输出模式下可控制端口输出高低电平,可以驱动LED,控制蜂鸣器,模拟通信协议&a…...

业务系统对接大模型的基础方案:架构设计与关键步骤
业务系统对接大模型:架构设计与关键步骤 在当今数字化转型的浪潮中,大语言模型(LLM)已成为企业提升业务效率和创新能力的关键技术之一。将大模型集成到业务系统中,不仅可以优化用户体验,还能为业务决策提供…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)
概述 在 Swift 开发语言中,各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过,在涉及到多个子类派生于基类进行多态模拟的场景下,…...
条件运算符
C中的三目运算符(也称条件运算符,英文:ternary operator)是一种简洁的条件选择语句,语法如下: 条件表达式 ? 表达式1 : 表达式2• 如果“条件表达式”为true,则整个表达式的结果为“表达式1”…...

基于Docker Compose部署Java微服务项目
一. 创建根项目 根项目(父项目)主要用于依赖管理 一些需要注意的点: 打包方式需要为 pom<modules>里需要注册子模块不要引入maven的打包插件,否则打包时会出问题 <?xml version"1.0" encoding"UTF-8…...

多模态大语言模型arxiv论文略读(108)
CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题:CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者:Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...
Swagger和OpenApi的前世今生
Swagger与OpenAPI的关系演进是API标准化进程中的重要篇章,二者共同塑造了现代RESTful API的开发范式。 本期就扒一扒其技术演进的关键节点与核心逻辑: 🔄 一、起源与初创期:Swagger的诞生(2010-2014) 核心…...

Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
Angular微前端架构:Module Federation + ngx-build-plus (Webpack)
以下是一个完整的 Angular 微前端示例,其中使用的是 Module Federation 和 npx-build-plus 实现了主应用(Shell)与子应用(Remote)的集成。 🛠️ 项目结构 angular-mf/ ├── shell-app/ # 主应用&…...

PHP 8.5 即将发布:管道操作符、强力调试
前不久,PHP宣布了即将在 2025 年 11 月 20 日 正式发布的 PHP 8.5!作为 PHP 语言的又一次重要迭代,PHP 8.5 承诺带来一系列旨在提升代码可读性、健壮性以及开发者效率的改进。而更令人兴奋的是,借助强大的本地开发环境 ServBay&am…...

实战三:开发网页端界面完成黑白视频转为彩色视频
一、需求描述 设计一个简单的视频上色应用,用户可以通过网页界面上传黑白视频,系统会自动将其转换为彩色视频。整个过程对用户来说非常简单直观,不需要了解技术细节。 效果图 二、实现思路 总体思路: 用户通过Gradio界面上…...