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…...
第19节 Node.js Express 框架
Express 是一个为Node.js设计的web开发框架,它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用,和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
蓝桥杯 2024 15届国赛 A组 儿童节快乐
P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡,轻快的音乐在耳边持续回荡,小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下,六一来了。 今天是六一儿童节,小蓝老师为了让大家在节…...
如何将联系人从 iPhone 转移到 Android
从 iPhone 换到 Android 手机时,你可能需要保留重要的数据,例如通讯录。好在,将通讯录从 iPhone 转移到 Android 手机非常简单,你可以从本文中学习 6 种可靠的方法,确保随时保持连接,不错过任何信息。 第 1…...
高危文件识别的常用算法:原理、应用与企业场景
高危文件识别的常用算法:原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件,如包含恶意代码、敏感数据或欺诈内容的文档,在企业协同办公环境中(如Teams、Google Workspace)尤为重要。结合大模型技术&…...
vue3 定时器-定义全局方法 vue+ts
1.创建ts文件 路径:src/utils/timer.ts 完整代码: import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...
算法:模拟
1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) 遍历字符串:通过外层循环逐一检查每个字符。遇到 ? 时处理: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: 与…...
MySQL 部分重点知识篇
一、数据库对象 1. 主键 定义 :主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 :确保数据的完整性,便于数据的查询和管理。 示例 :在学生信息表中,学号可以作为主键ÿ…...
群晖NAS如何在虚拟机创建飞牛NAS
套件中心下载安装Virtual Machine Manager 创建虚拟机 配置虚拟机 飞牛官网下载 https://iso.liveupdate.fnnas.com/x86_64/trim/fnos-0.9.2-863.iso 群晖NAS如何在虚拟机创建飞牛NAS - 个人信息分享...
