考虑分库分表的场景下,如何实现通过Flyway在多数据源时做数据库版本更新。
实现方案
-
首先,关闭Flyway自动配置
spring:
flyway:
#关闭flyway自动配置,自定义实现
enabled: false
-
其次,配置数据库多数据源
datasource:
# 主库数据源
master:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.16.155:3306/edu01?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
username: root
password: 123456
# 从库数据源
slave:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://192.168.16.155:3306/edu02?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
username: root
password: 123456
-
自定义实现Flyway配置类,遍历数据源进行数据库迁移
package com.ruoyi.system.config;
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import lombok.extern.slf4j.Slf4j;
import org.flywaydb.core.Flyway;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
import java.util.Map;
@Slf4j
@Configuration
@EnableTransactionManagement
public class FlywayConfig {
@Autowired
private DataSource dataSource;
@Bean
public void migrate() {
log.info("开始执行数据库迁移");
DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
Map<String, DataSource> dataSourceMap = ds.getDataSources();
dataSourceMap.forEach((k, v) -> {
Flyway flyway = Flyway.configure().
dataSource(v)
.baselineOnMigrate(true)
.baselineVersion("0.1") // 基线版本
.baselineDescription(k + "初始化")
.locations("classpath:db/migration") // sql脚本存放地址
.load();
flyway.migrate(); // 执行版本迁移
log.info("{} 数据库迁移完成", k);
});
}
}