spring boot 集成 flyway依赖 做数据库迁移,让部署没烦恼
2026/6/6 6:24:01 网站建设 项目流程

flyway 是一个敏捷工具,用于数据库的移植。采用 Java 开发,支持所有兼容 JDBC 的数据库。

主要用于在你的应用版本不断升级的同时,升级你的数据库结构和里面的数据。

还是直接上代码
第一步:
mysql5.7 直接引入即可, 可不指定flyway的版本

<!--Flyway数据库迁移 依赖 他会根据spring boot版本 默认下载兼容依赖 不需要写版本号--><dependency><groupId>org.flywaydb</groupId><artifactId>flyway-core</artifactId></dependency>

mysql8 :使用高版本的flyway 要引入两个 依赖 要么会报错

<dependency><groupId>org.flywaydb</groupId><artifactId>flyway-core</artifactId><version>12.7.0</version></dependency><dependency><groupId>org.flywaydb</groupId><artifactId>flyway-mysql</artifactId><version>12.7.0</version></dependency>

第二步:配置文件

spring:flyway:# 是否启用flyway enabled:true# 禁止清理数据库表 # clean 操作是Flyway的一个功能,可以清空数据库中的所有对象(比如表、视图、存储过程等), #以便进行全新的数据库迁移。在开发和测试阶段,这可能是有用的,因为它可以确保每次都从一个干净的数据库状态开始运行。 #但在生产环境中,执行 clean 操作可能会导致数据丢失,因此通常需要禁用它 clean-disabled:true# 如果数据库不是空表,需要设置成true,当迁移数据库存在但没有元数据的表时,自动执行基准迁移 #当数据库中不存在迁移历史记录表时,Flyway会自动创建该表,并将当前已经存在的数据库对象标记为已迁移状态。 #当数据库中存在迁移历史记录表,但版本号低于最新的迁移脚本版本时, #Flyway也会自动创建一个基线版本,从而将现有的数据库对象标记为已迁移状态,并开始应用最新的迁移脚本。 #这样做的目的是确保在已有数据库上使用Flyway进行迁移时,无论数据库是否已经有迁移历史记录, #都能够正确地进行迁移操作。这在初始化应用程序时特别有用,因为它允许你在部署应用程序到新环境时, # 自动初始化数据库并应用最新的迁移脚本。 baseline-on-migrate:true# 开始执行基准迁移时对现有的schema的版本打标签,默认值为1#baseline-version:1# 编码格式,默认UTF-8encoding:UTF-8# 迁移sql脚本文件存放路径,默认db/migration # 如果配置完这个路径,也手动创建了这个目录 启动服务 一直报错 这个目录找不到 # 可在目录里创建一个.keep的空文本文件,以确保该目录在应用程序启动期间被编译并可用,以避免错误。 locations:classpath:db/migration # 迁移sql脚本文件名称的前缀,默认V前缀标识,默认值V表示Versioned,R表示Repeatable,U表示Undo#FlywaySQL文件分为VersionedRepeatableUndo三种: #Versioned用于版本升级,每个版本有唯一的版本号并只能执行一次.#Repeatable可重复执行,Flyway检测到Repeatable类型的SQL脚本的 checksum 有变动,#Flyway就会重新应用该脚本.它并不用于版本更新,这类的 migration 总是在Versioned执行之后才被执行。 #Undo用于撤销具有相同版本的版本化迁移带来的影响。但是该回滚过于粗暴,过于机械化,一般不推荐使用。 # 一般建议使用Versioned模式来解决 sql-migration-prefix:V# 迁移sql脚本文件名称的分隔符,默认2个下划线__ sql-migration-separator:__ # 迁移sql脚本文件名称的后缀 sql-migration-suffixes:.sql # 迁移时是否进行校验,默认truevalidate-on-migrate:true

第三步:问题
手动在资源目录下 创建 db/migration文件夹
发现启动项目 还会报错没有文件夹
运行的时候报错,找不到db/migration找不到文件。
IllegalStateException: Cannot find migrations location in: [classpath:db/migration]

解决方案:
对于旧版本的库,我们可能需要在resources/db/migration/ 中创建一个名为.keep的空文本文件,以确保该目录在应用程序启动期间被编译并可用,以避免错误。

idea集成插件
Flyway Migration Creation


第四步:使用插件:
右键 资源文件夹 db/migration

你不需要写
V版本号__ 前缀 只需要写描述 他会自动给你创建版本号

第五步:
sql脚本编写:

/* Navicat Premium Data Transfer Date: 10/04/2024 15:10:25 测试 数据迁移表 文件名命名规则 大写的V开头 V版本号__表名_要执行什么_xxx_xxx.sql ==================================================================== 注意:如果从 Navicat 工具里导出的sql文件 文件默认会有 DROP TABLE IF EXISTS `test_cg`; 这句命令 如果是初始化数据库 有没有这句话都没影响, 为了防止【使用中数据表】出现被删除的意外 不建议sql脚本里存在【删除表】的命令 如果从Navicat导出来来的数据表 建议手动 把这个命令【 DROP TABLE IF EXISTS `test_cg`;】 给删除掉 ===================================================================== 如果当前的sql脚本是执行整个库! 是通过Navicat导出的整个库 1. 导出后 DROP TABLE IF EXISTS `test_cg`;【这个命令一一删除掉!】 2. flyway_schema_history 这个表给删除掉 这个表 会在启动项目的时候 flyway插件 初始化出来 比如 开发完成的库 需要部署上线 肯定开发库里已经有了 flyway_schema_history这个表 但是 生成的数据库 是一个新的数据库 所以为了让sql脚本执行 需要把flyway_schema_history这个表删除掉 在 部署 正式项目 会自动生产出 flyway_schema_history 这个表 然后flyway会一一执行 sql脚本 ===================================================================== 已经有 flyway_schema_history 这个表的 数据库 【不要删除这个表 或者 删除表里的数据】 因为这个表里记录了 已经执行过的sql脚本 防止重复执行的! ====================================================================== 项目集成了flyway数据库迁移插件 不管创建表 表里新增字段、修改字段、删除字段、初始化表里的基础数据 都建议写成sql脚本 放在 db/migration文件夹下 可以用 Navicat -> 设计表 ->设计后【不要点保存】->点【sql预览】-> 复制sql到项目的sql脚本里 让项目执行sql脚本创建表结构 如果 【点了保存】 表已经存在 在启动项目会报错【表存在】 后续 有更简便方案 再优化 ====================================================================== 注: sql脚本里 编写 删除命令 一定要慎重 执行过的sql脚本 不要修改 连格式化或者空格都别做!!! 如果改动了启动项目会报错 他好像会检测文件 每次创建一个新文件使用 */SETNAMES utf8mb4;SETFOREIGN_KEY_CHECKS=0;-- ------------------------------ Table structure for test_cg-- ----------------------------CREATETABLE`test_cg`(`id`bigintUNSIGNEDNOTNULLAUTO_INCREMENT,`user_id`intNULLDEFAULTNULLCOMMENT'登录用户ID',`username`varchar(100)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNULLDEFAULTNULLCOMMENT'登录用户名称',`remark`varchar(255)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNULLDEFAULTNULLCOMMENT'备注',`create_time`timestampNULLDEFAULTNULLCOMMENT'操作时间',`test_add`varchar(100)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNULLDEFAULTNULLCOMMENT'测试字段',`aaa`varchar(100)CHARACTERSETutf8mb4COLLATEutf8mb4_unicode_ciNULLDEFAULTNULLCOMMENT'加个字段',PRIMARYKEY(`id`)USINGBTREE,INDEX`idx_username`(`username`)USINGBTREE)ENGINE=InnoDBAUTO_INCREMENT=4CHARACTERSET=utf8mb4COLLATE=utf8mb4_unicode_ciCOMMENT='代码生成测试表'ROW_FORMAT=DYNAMIC;SETFOREIGN_KEY_CHECKS=1;

项目启动后 他会自动执行 这里的sql

flyway弊端 : sql脚本 需要你手动编写 不能自动生成 很烦!

据说下面的这个依赖可以做到 根据数据库表自动生成脚本
因为项目已经集成了 flyway 懒得换
有兴趣的小伙伴可以尝试装 这个Liquibase 依赖

Liquibase:Liquibase是一个开源的数据库变更管理工具,它可以通过XML或YAML等配置文件来描述数据库变更,支持基于Java代码的迁移脚本生成。你可以定义实体类,并通过Liquibase Maven插件或命令行工具生成相应的数据库迁移脚本。

补充:
在使用的过程中发现了一个问题
场景:
git 上两个分支 A分支 7月3号创建了 表 B分支 7月4号 创建了表 但是B分支先合并到主分支上线 过两天A分支合并到主分支后上线 这时候 A分支上线的时候
就会报错 “Detected resolved migration not applied to database: 20240703171057” 这个问题

对于这个问题 解决方案 如下
官方的参数
官方文档地址
https://documentation.red-gate.com/fd/out-of-order-224919730.html

第一种 官方文档的 out-of-order 这个参数 改为 ture 默认false

spring: flyway:#可能会出现 A 写了 V1 脚本,B 写了 V2 脚本,# B 的代码先合并进去了,V2 脚本先执行了,此时 A 的 V1 脚本受版本号只能增加的要求不能再执行# 为了解决这个问题 可把这个参数设置 为true 是否可以无序执行 他默认是false 严格按照 顺序执行# 一般不建议 设置为true 因为如果脚本有依赖关系 有可能有些脚本执行会报错# 强烈建议 A 将 V1 脚本版本号改为 V3。所以为了脚本稳定 建议按顺序执行 实在没办法再开启 无序执行# 如果长期开 true 写脚本的时候 尽量防止 sql脚本文件之间的依赖# 比如 两个sql脚本 一个是创建表 一个是 给 这个表追加字段# 如果是无序执行 有可能 追加字段先执行 就会报错 因为表还没创建成功out-of-order:true

第二种:手动改

第三种:
多个分支 多个团队 用一个公共的 migration 迁移目录

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询