数据库迁移
Flyway(类比 Laravel Migrations)
Flyway 是 Java 生态中最流行的数据库迁移工具,Spring Boot 对其有开箱即用的支持。
对比
| Laravel | Flyway |
|---|---|
database/migrations/ | src/main/resources/db/migration/ |
php artisan make:migration | 手动创建 SQL 文件 |
php artisan migrate | 应用启动时自动执行 |
php artisan migrate:rollback | 不支持回滚(需写 undo SQL) |
| 迁移文件是 PHP 类 | 迁移文件是纯 SQL |
配置
yaml
# application.yml
spring:
flyway:
enabled: true
locations: classpath:db/migration # 迁移文件目录
baseline-on-migrate: true # 对已有数据库启用基线添加依赖:
xml
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-mysql</artifactId>
</dependency>迁移文件命名规则
V1__create_users_table.sql
V2__add_email_to_users.sql
V3__create_posts_table.sql命名格式:V{版本号}__{描述}.sql
- 版本号:数字,递增(如
1、1_1、2) - 双下划线
__:分隔符 - 描述:简短英文,单词用下划线连接
迁移文件内容
sql
-- V1__create_users_table.sql
CREATE TABLE users (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(100) NOT NULL,
email VARCHAR(255) NOT NULL UNIQUE,
age INT,
created_at DATETIME DEFAULT CURRENT_TIMESTAMP,
updated_at DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);
-- V2__add_email_verified.sql
ALTER TABLE users ADD COLUMN email_verified_at DATETIME NULL;和 Laravel 不同,Flyway 不提供 Schema Builder(
Schema::create('users', function($t) { ... })),你直接写原生 SQL。好处:SQL 在所有环境完全一致,不会因为 PHP 版本差异导致生成不同 SQL。 坏处:没有 IDE 提示,需要自己记住字段类型语法。
执行时机
Spring Boot 应用启动时自动执行尚未运行过的迁移文件,不需要手动 php artisan migrate。
java
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
// 启动过程中会:
// 1. 检查 db/migration/ 目录下未执行的 SQL
// 2. 按版本号顺序执行
// 3. 记录执行历史到 flyway_schema_history 表
// 4. 启动完成,可正常使用数据库
SpringApplication.run(DemoApplication.class, args);
}
}状态查看
sql
-- flyway 会在数据库中创建一张历史记录表
SELECT version, description, installed_on, success
FROM flyway_schema_history;| version | description | installed_on | success |
|---|---|---|---|
| 1 | create users table | 2026-04-25 10:00:00 | 1 |
| 2 | add email to users | 2026-04-25 10:00:05 | 1 |
Liquibase(Flyway 的替代方案)
另一个流行的迁移工具。Flyway 用 SQL 文件,Liquibase 用 XML/YAML/JSON 描述变更。
| 特性 | Flyway | Liquibase |
|---|---|---|
| 文件格式 | 纯 SQL | XML / YAML / JSON / SQL |
| 学习成本 | 低(直接用 SQL) | 高(需要学 DSL) |
| 回滚 | 需手工写 undo SQL | 支持自动生成回滚 |
| 社区 | 大 | 中 |
| Spring Boot 整合 | 自动配置 | 自动配置 |
⚠️ 常见坑
1. 修改已执行过的迁移文件会报错
Flyway 检查文件的 checksum,如果你修改了已执行过的
V1__xxx.sql并重启,会报:Migration checksum mismatch for migration version 1解决方案:
- 开发阶段:删掉
flyway_schema_history表对应记录,重新执行- 生产环境:永远不要修改已执行的迁移文件,写新的
V2__xxx.sql来变更
2. 没有 down 方法
Laravel 的
down()方法允许回滚,Flyway 没有回滚概念。如果需要回滚:
- 开发中:删库重建(反正没数据)
- 生产中:写
V2__undo_add_email_to_users.sql手动做反向操作
3. 多环境数据库基线问题
如果项目已经有一个线上数据库(没有用 Flyway 管理),需要配置
baseline-on-migrate: true,Flyway 会以当前数据库状态为基线,后续迁移基于这个基线运行。另一种方案:手动在
flyway_schema_history表中插入一条基线记录,告诉 Flyway "当前版本是 V1"。
4. Spring Boot + Flyway 版本要匹配
Spring Boot 3.x 需要 Flyway 9.x+。版本不匹配时会报兼容性错误。