【发布时间】:2018-08-24 11:37:26
【问题描述】:
情况
我有一个模块化的Spring Boot 项目。作为数据库模式管理器,我想使用Flyway。
如前所述,该项目是模块化的。这是因为会有不同的配置使用不同的模块。这意味着,我想将与模块相关的所有内容打包到它的特定项目中。有了Flyway,这似乎没那么简单。
问题
我的理想想象:
ApplicationA
|
|_Module1
| |
| |_db/migration
| |
| |_V1__InitModule1Tables
| |_V2__MigrateSomeTable
|
|_Module2
|
|_db/migration
|
|_V1__InitModule2Tables
|_V2__MigrateSomeTable
每个模块都独立定义自己的飞行脚本,因为它们无论如何都不知道彼此的存在。每个模块显然都需要在共享数据库中拥有自己的飞行路线历史记录表。这样整个系统就解耦了,用Module1和Module3配置下一个应用ApplicationB不会很麻烦。
嗯,我没有找到任何配置可能让Flyway 达到这个解决方案。
我尝试过的
在每个模块中做这样的事情显然是个坏主意,因为 bean 的初始化/执行顺序相当随机,导致当我需要它们用于其他配置时没有创建表。看起来也很乱。
@Configuration
public class Module1Config {
@Autowired
public void flyway(DataSource dataSource) {
Flyway flyway = new Flyway();
flyway.setBaselineOnMigrate(true);
flyway.setTable(flyway.getTable() + "-module1");
flyway.setDataSource(dataSource);
flyway.migrate();
}
}
我不认为我是第一个尝试实现这一目标的人。我怎样才能达到所需的模块化Flywayconfiguration?
* 更新 *
解决方案
按照重复主题建议的方式工作的以下解决方案对我有用:
我在我的 base 模块中创建了一个配置模板,它被任何其他模块使用,因为它提供了日志记录和日志记录等全局功能。
public abstract class FlywayConfig {
private final String moduleName;
public FlywayConfig(String moduleName) {
this.moduleName = moduleName;
}
private final String baseScriptLocation = "classpath:db.migration.";
@Autowired
public void migrate(DataSource dataSource) {
Flyway flyway = new Flyway();
flyway.setDataSource(dataSource);
flyway.setSchemas(moduleName.toUpperCase());
flyway.setLocations(baseScriptLocation + moduleName.toLowerCase());
flyway.migrate();
}
}
在每个模块中,我只是简单的扩展了这个配置类
@Configuration
public class BaseConfig extends FlywayConfig {
public static final String MODULE_NAME = "base";
public BaseConfig() {
super(MODULE_NAME);
}
}
而我将 flyway 脚本保存在 db.migration.*MODULE_NAME*
【问题讨论】:
-
您是否设法使用您的
BaseConfig在集成测试中运行迁移?
标签: spring-boot database-migration flyway modularity spring-config