一、前言
Flyway 是一款开源的数据库版本管理工具,它更倾向于规约优于配置的方式。Flyway 可以独立于应用实现管理并跟踪数据库变更,支持数据库版本自动升级,并且有一套默认的规约,不需要复杂的配置,Migrations 可以写成 SQL 脚本,也可以写在 Java 代码中,不仅支持 Command Line 和 Java API,还支持 Build 构建工具和 Spring Boot 等,同时在分布式环境下能够安全可靠地升级数据库,同时也支持失败恢复等。
二、简单介绍
2.1 主要特性
1 | 普通 SQL:纯 SQL 脚本(包括占位符替换)没有专有的XML格式,没有锁定 |
2.2 运行原理
当 Flyway 连接数据库中的 schema 后,会先检查是否已存在 flyway_schema_history 表,如果没有则创建。该表用于跟踪数据库的状态,如数据迁移的版本,迁移成功状态等信息。
当 flyway_schema_history 存在后,Flyway 会扫描文件系统或应用中的 classpath 目录的数据迁移文件,然后根据它们的版本号进行按序迁移,如下图:
flyway_schema_history 表记录的内容如下:
installed_rank | version | description | type | script | checksum | installed_by | installed_on | execution_time | success |
---|---|---|---|---|---|---|---|---|---|
1 | 1 | Initial Setup | SQL | V1__Initial_Setup.sql | 1996767037 | axel | 2016-02-04 22:23:00.0 | 546 | true |
2 | 2 | First Changes | SQL | V2__First_Changes.sql | 1279644856 | axel | 2016-02-06 09:18:00.0 | 127 | true |
由于 flyway_schema_history 表中记录了迁移的版本号,如果文件的版本号小于或等于标记为当前版本的版本号,则忽略它们不执行。
上边描述的内容或许对读者来说还不够直观,那么下面我们就开始进行实战演练。
三、实战
测试环境:Mysql5.7
新建一个 Maven 项目。
3.1 添加依赖
1 | <!-- flyway --> |
3.2 配置数据迁移文件
在项目的 src/main/resources 下创建 db/migration 目录,该目录下放置需要数据迁移的文件。
数据迁移文件名称格式为:V[version]__[name].sql。
注意:名称中[version]和[name]之间是两个下划线!
本次测试新建名为 V1__Create_person_table.sql 的文件,内容如下:
1 | create table PERSON ( |
版本 1 数据迁移的内容是创建一张 PERSON 表。
3.3 编码
1 | public class FlywayTest { |
执行结果如下图:
图中,数据库 flyway 中创建了 flyway_schema_history 表和 PERSON 表,数据成功迁移到指定数据库中。
当系统升级时又需要做数据迁移,我们只需在 db/migration 目录下再放置新版本的 sql 文件即可。
比如,我们再新建一个名为 V2__Add_people.sql 文件,内容如下:
1 | insert into PERSON (ID, NAME) values (1, 'Axel'); |
版本 2 的数据迁移内容是往 PERSON 表中插入 3 条数据。
再次执行上边的程序,演示效果图如下:
四、Spring Boot 整合
4.1 添加依赖
1 | <dependency> |
4.2 application.yml
1 | spring: |
将需数据迁移的 sql 文件放置到 db/migration/mysql 目录中,启动 Spring Boot 项目即可运行 Flyway 进行数据迁移。
测试结果同上,此处不再张贴。
注意事项:
如果 flyway 不是项目初期引入,而是在数据库已有表的情况下引入时必须设置 baseline-on-migrate: true,设置该配置启动项目后,flyway 就会在数据库中创建 flyway_schema_history 表,并且会往该表中插入一条 version = 1 的建表记录,如果迁移数据有 V1__ 开头的文件,扫描文件会忽略该文件不执行迁移,进而可能引发其他迁移数据出错的问题。
以上边的 2 个 sql 文件为例进行演示,flyway 库中已有一张 test 表,运行程序结果如下:
由于忽略了 V1__Create_person_table.sql ,库中就不创建 PERSON 表,在迁移 V2__Add_people.sql 文件中的数据时必然失败。
解决方案先删除flyway_schema_history 表, 然后配置文件中设置 baseline-version: 0,或修改数据迁移文件版本名称,最后再次启动应用即可。