一、前言
本文主要介绍 Flyway 在实际中的应用。在实际项目中应用 Flyway 主要要解决两个问题:
- 如何管理多个数据库;
- 如何管理不同环境的数据库。
本文仍然使用 Flyway maven 插件,Command line 和 gradle 实际上和 maven 是类似的,Java API 能提供一些钩子
。
二、Flyway 管理多个数据库
1、建立迁移脚本目录
蜂窝要管理两个数据库,为每个数据库建立一个 SQL 迁移脚本目录。如图,在 db/migration
目录中,为 info 和 cen 库各自建立一个目录:
2、修改 pom.xml
(1)添加 Flyway 插件
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>5.0.5</version>
</plugin>
(2)添加 executions
在 executions
标签中为两个数据库实例各添加一个 execution
,用 id
区分。注意指定 SQL 迁移脚本的目录位置 location
。如下指定了 info 库的参数;cen 库类似,只要修改连接参数、用户名和密码即可:
<execution>
<id>info</id>
<phase>compile</phase>
<goals>
<goal>migrate</goal>
</goals>
<configuration>
<url>jdbc:mysql://hostname:port#/db_name</url>
<user>username</user>
<password>password</password>
<locations>
<location>filesystem:src/main/resources/db/migration/info</location>
</locations>
</configuration>
</execution>
(3)执行数据库迁移
- 导出 info 和 cen 库原有数据和结构,分别放入各自的
db/migration
目录,命名为V1__Base_line.sql
,运行命令:mvn flyway:baseline
; - 执行数据库结构或内容修改:
mvn flyway:migrate
; - 注意:为了明确指定执行某个数据的迁移脚本,必须加上
execution
中的id
,如要执行 info 库的迁移:mvn flyway:migrate@info
。
三、Flyway 管理不同环境的数据库
在实际项目中,不仅有多个数据库实例,还有多个环境,如开发环境、测试环境和生产环境。为了能够统一管理,需要为不同环境配置不同参数。
(1)profile
在 pom.xml 中,添加 profiles
,并添加三个 profile
:dev
、qa
和 prod
,分别管理不同环境的数据库连接、用户名和密码:
默认激活 dev
环境。
(2)占位符
把 configuration 中的参数替换为占位符
:
<configuration>
<url>${info.url}</url>
<user>${info.user}</user>
<password>${info.password}</password>
<locations>
<location>filesystem:src/main/resources/db/migration/info</location>
</locations>
</configuration>
(3)在不同环境执行脚本迁移
给 mvn 命令添加参数 -P
,mvn flyway:migrate@info -P 环境id
。
如在生产环境执行迁移:mvn flyway:migrate@info -P prod
。
四、配置钩子
Flyway 提供多种钩子,可以在执行 migrate,info,clean,validate,baseline 等命令前后
执行。
Java API 提供了 FlywayCallback
接口,或者可以继承 BaseFlywayCallback
,实现所需方法。
最后在 pom.xml 文件配置 callback
。在 configuration
标签里添加:
<callbacks>
<callback>CallbackClassName</callback>
</callbacks>
五、参考文献
Stack Overflow “How to use Flyway configuration to handle multiple databases”
Flyway FAQ “Does Flyway support multiple schemas?”