目录
前言:本文章专用于因版本问题导致springboot整合flyway不成功无法自动迁移的情况
【pom.xml】
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1.1-jre</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>5.8.0.M4</version>
</dependency>
【启动类】
@SpringBootApplication(exclude = {FlywayAutoConfiguration.class})
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
【配置属性类】
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Configuration;
/**
* @author JHL
* @version 1.0
* @date 2022/8/19 12:20
* @since : JDK 11
*/
@ConfigurationProperties(prefix = FlywayProperties.PREFIX)
@Configuration
public class FlywayProperties {
public static final String PREFIX = "flyway";
/**
* sql脚本文件路径
*/
private String flywayScriptLocation = "classpath:db/migration/";
/**
* 自动迁移
*/
private Boolean flywayAutoMigration = true;
/**
* 发生错误的时候清理表
*/
private Boolean cleanOnValidationError = true;
/**
* 结束时间自动清理表
*/
private Boolean autoCleanTable = true;
public Boolean getCleanOnValidationError() {
return cleanOnValidationError;
}
public void setCleanOnValidationError(Boolean cleanOnValidationError) {
this.cleanOnValidationError = cleanOnValidationError;
}
public Boolean getAutoCleanTable() {
return autoCleanTable;
}
public void setAutoCleanTable(Boolean autoCleanTable) {
this.autoCleanTable = autoCleanTable;
}
public String getFlywayScriptLocation() {
return flywayScriptLocation;
}
public void setFlywayScriptLocation(String flywayScriptLocation) {
this.flywayScriptLocation = flywayScriptLocation;
}
public Boolean getFlywayAutoMigration() {
return flywayAutoMigration;
}
public void setFlywayAutoMigration(Boolean flywayAutoMigration) {
this.flywayAutoMigration = flywayAutoMigration;
}
}
【配置类】
import com.alibaba.druid.pool.DruidDataSource;
import com.google.common.collect.Maps;
import org.apache.commons.lang3.StringUtils;
import org.flywaydb.core.Flyway;
import org.flywaydb.core.api.MigrationInfo;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import java.util.Map;
/**
* @author JHL
* @version 1.0
* @date 2022/8/19 11:17
* @since : JDK 11
*/
@Configuration
public class FlywayConfig implements InitializingBean, DisposableBean {
private static final Logger log = LoggerFactory.getLogger(FlywayConfig.class);
@Autowired
private FlywayProperties flywayProperties;
@Autowired
private DruidDataSource druidDataSource;
@Override
public void afterPropertiesSet() throws Exception {
if (flywayProperties.getFlywayAutoMigration()) {
migrateAutomatically(druidDataSource.getName());
log.info("########### [ flyway 数据库初始化成功! ] ###########");
}
}
@Override
public void destroy() throws Exception {
if (flywayProperties.getAutoCleanTable() && flywayProperties.getFlywayAutoMigration()) {
cleanAutomatically(druidDataSource.getName());
log.info("########### [ flyway 数据库表清空成功! ] ###########");
}
}
private Map<String, Flyway> flyways() {
Map<String, Flyway> flywayMap = Maps.newHashMap();
String migrationFilesLocation = null;
Flyway flyway = null;
migrationFilesLocation = flywayProperties.getFlywayScriptLocation();
flyway = new Flyway();
flyway.setDataSource(druidDataSource.getUrl(), druidDataSource.getUsername(), druidDataSource.getPassword());
flyway.setLocations(migrationFilesLocation);
if (flywayProperties.getCleanOnValidationError()) {
flyway.setCleanOnValidationError(true);
}
if (flywayProperties.getFlywayAutoMigration()) {
flyway.setInitOnMigrate(true);
}
flywayMap.put(druidDataSource.getName(), flyway);
return flywayMap;
}
private void migrateAutomatically(String dbName) {
Map<String, Flyway> flywayMap = flyways();
flywayMap.get(dbName).migrate();
}
private void cleanAutomatically(String dbName) {
Map<String, Flyway> flywayMap = flyways();
flywayMap.get(dbName).clean();
}
private void checkState(String dbName) {
Map<String, Flyway> flywayMap = flyways();
MigrationInfo[] pendingMigrations = flywayMap.get(dbName).info().pending();
if (pendingMigrations != null) {
throw new RuntimeException(dbName + "-" + StringUtils.join(pendingMigrations, ","));
}
}
}
【配置文件】
# 数据库脚本版本控制
flyway:
flywayScriptLocation: classpath:db/migration/
flywayAutoMigration: true
cleanOnValidationError: true
autoCleanTable: true
【IDEA插件支持】
Flyway Migration Creation
用于按照flyway的规则自动生成数据库脚本的文件名称的插件
SQL 脚本命名规范如下
Prefix+Version+Separator+Description+Suffix
Prefix 前缀:V 代表版本迁移,U 代表撤销迁移,R 代表可重复迁移
Version 版本号:版本号通常 . 和整数组成
Separator 分隔符:固定由两个下划线 __ 组成
Description 描述:由下划线分隔的单词组成,用于描述本次迁移的目的
Suffix 后缀:如果是 SQL 文件那么固定由 .sql 组成,如果是基于 Java 类则默认不需要后缀