数据库版本管理这件事,很多人一开始都没当回事。代码进了 Git,接口文档有 Swagger,唯独数据库结构停留在“靠人传话”的阶段:谁改了表,就在群里说一句,或者丢个 sql 文件到共享目录。直到某次上线,生产环境的表漏加了一个字段,服务启动直接报错,一群人翻聊天记录才找到原因。后来我把 Flyway 集成进 Spring Boot 项目,才算是把这笔“烂账”彻底理顺了。
Flyway 是个数据库迁移工具,核心思路就是用一个统一目录管理所有数据库变更脚本,并且通过一张历史记录表控制哪些脚本执行过、哪些还没执行,按顺序自动补齐。对 Spring Boot 项目来说,它做得更彻底:应用启动时自动检查并执行迁移,几乎不用额外写触发代码。这篇文章就围绕 Spring Boot 集成 Flyway 的完整过程来写,包括依赖引入、配置参数、脚本规范、常见坑和排查思路,给需要的人一个可以直接照着做的参考。
我用的环境是 Spring Boot 2.7.18 + Flyway 8.5.13,如果你是 Spring Boot 3.x,版本对应关系会略有差异,下面会单独列出。文章里的内容基本都是我真实操作过的场景,不是只说“怎么配”,更重要的是解释“为什么这么配”。
1. 为什么要给数据库做版本管理
1.1 没有版本管理的数据库是什么状态
先说一个我接手过的项目。代码仓库里有两个分支,一个在开发新功能,一个在修线上 Bug。开发分支加了一张订单扩展表,线上 Bug 分支改了一个字段长度。等合并的时候,谁也不知道这两个变更是不是都执行过,DBA 手里有一堆零散的 sql 文件,文件名是 20240111_update.sql 这种,根本分不清哪个执行过、哪个没执行。
这种状态在中小团队里太常见了。没有数据库版本控制,直接带来的问题有三个:
- 变更记录靠人脑记忆,换个人就断档。
- 不同环境的数据库结构漂移,开发环境能跑,测试环境就挂。
- 并发开发时,两个人都改了同一张表,合并后结构对不上。
这三个问题的根子,就是把“数据库结构”当成了代码仓库之外的游离资产。而实际上,表结构、初始化数据、字段变更,都是应用的一部分,理应和代码一起版本化、可追溯、可回放。
1.2 Flyway 是怎么解决这个问题的
Flyway 的模型非常简单。你在 classpath:db/migration(默认位置)放一堆 SQL 脚本,脚本按约定命名,比如 V1__create_user_table.sql、V2__add_email_to_user.sql。第一次启动时,Flyway 会建一张名为 flyway_schema_history 的表,然后把执行过的脚本版本、校验值、执行时间都记进去。
以后每次应用启动,Flyway 会做两件事:
- 扫描 classpath 下的迁移脚本。
- 对比
flyway_schema_history表里已执行的记录,找出哪些是新脚本,按版本号顺序执行。
这样带来的好处是实打实的:同一套脚本在所有环境按相同顺序执行,不会漏,也不会重复。数据库结构从“薛定谔的猫”变成了可审计、可回放的状态。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. 环境准备与版本兼容问题
2.1 Spring Boot 与 Flyway 的版本对应关系
这一步是新手最容易卡住的,先说清楚。Spring Boot 不是自己实现了 Flyway,而是通过 spring-boot-dependencies 管理了 Flyway 的版本。不同 Spring Boot 版本对应的 Flyway 版本差异很大,直接决定了你能不能无脑加依赖。
我整理几个常用对应关系,这些是基于我实际验证过的。
| Spring Boot 版本 | Flyway 版本(默认依赖管理) | 需要注意的点 |
|---|---|---|
| 2.7.x | 8.5.x | 兼容 Flyway 8 和 9 的大多数写法,社区资料多 |
| 3.0.x | 9.16.x | 官方推荐新项目用这个组合,但 API 有调整 |
| 3.1.x | 9.22.x | 与 3.0 差异不大 |
| 3.2.x | 9.22.x | 注意 Java 17 要求,旧 JDK 8 项目升不动 |
这里有个很多人踩过的坑:如果你用 Spring Boot 3.x + Flyway 10.x(手动指定版本),Flyway 10 改了部分 API,并且默认不再支持 spring.flyway 下的一些旧属性,需要你额外引入 flyway-mysql 或 flyway-database-postgresql 模块。
2.2 Maven 依赖添加
我用的是 Spring Boot 2.7.18,Flyway 版本由 Boot 管理,所以只需要在 pom.xml 里加一个依赖:
xml复制<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
使用 MySQL 数据库时,Flyway 8.2 以后从 flyway-core 里拆分了数据库支持模块,所以还需要加 flyway-mysql 依赖,不然启动会报 Unsupported Database: MySQL。
xml复制<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
</dependency>
如果你用的是 PostgreSQL,则不需要额外的 flyway-mysql,但在 Flyway 10 版本下要加 flyway-database-postgresql。
如果 Spring Boot 默认管理的 Flyway 版本和你需要的不一致,也可以手动覆盖:
xml复制<properties>
<flyway.version>9.22.3</flyway.version>
</properties>
覆盖之前先确认目标 Flyway 版本能兼容你当前的数据库驱动和
