yeg
2026-09-05 92f32acd847ea1700590bc669750f23ef499840e
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
package com.battery.business.runtime;
 
import javax.sql.DataSource;
 
import com.alibaba.druid.pool.DruidDataSource;
import org.flywaydb.core.Flyway;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
/**
 * 在 MyBatis 使用的主数据源上执行版本化迁移。
 *
 * <p>项目使用自定义 Druid 数据源,因此不使用 Spring Boot 默认 Flyway 自动装配。</p>
 */
@Configuration
public class FlywayMigrationConfig
{
    @Bean(name = "flywayMigrationInitializer", initMethod = "migrate")
    public FlywayMigrationInitializer flywayMigrationInitializer(@Qualifier("masterDataSource") DataSource dataSource)
    {
        if (!(dataSource instanceof DruidDataSource druidDataSource))
        {
            throw new IllegalStateException("Flyway requires the configured Druid master datasource");
        }
        Flyway flyway = Flyway.configure()
                // Flyway 直接使用连接参数,避免 MySQL 拒绝可选的 performance_schema 探测后
                // Druid 将池内连接标记为不可用。
                .dataSource(druidDataSource.getUrl(), druidDataSource.getUsername(), druidDataSource.getPassword())
                // 旧迁移链仅作历史保留,新库从最终业务基线初始化。
                .locations("classpath:db/migration-final")
                .baselineOnMigrate(false)
                .validateOnMigrate(true)
                .outOfOrder(false)
                .cleanDisabled(true)
                .load();
        return new FlywayMigrationInitializer(flyway);
    }
 
    /** 通过独立生命周期 Bean 显式执行迁移,便于验证启动顺序。 */
    public static final class FlywayMigrationInitializer
    {
        private final Flyway flyway;
 
        public FlywayMigrationInitializer(Flyway flyway)
        {
            this.flyway = flyway;
        }
 
        public void migrate()
        {
            flyway.migrate();
        }
    }
}