添加依赖
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
<version>6.4.4</version>
</dependency>
我用的是如上版本,太新的版本,mysql5.7不支持,最高支持到哪个版本得自己去试,如下版本别试了,我已经试过了:
处理问题过程
因为ruoyi-vue-pro模块比较多,加之刚接触springboot,所以搞了好久才让这个项目成功运行flyway(不知道把依赖加哪个模块下),网上好多就是费话太多了,也不能说费话,只能说不适合这个项目,按网上说的就是加依赖,加配置,最后resources/db/migration,启动,在日志文件 里可以看到FlywayAutoConfiguration ,这个类里只执行了如下:
@Bean
@ConfigurationPropertiesBinding
public StringOrNumberToMigrationVersionConverter stringOrNumberMigrationVersionConverter() {
return new StringOrNumberToMigrationVersionConverter();
}
然并卵,
最后,没有最最后了,因为他们没说要不要手动建库,又搞了好久,还是不行,放弃几天,不搞了。
然后,不服输,搞不出来心里难受,接着弄,网上过来过去就是那几片文章,最后又看flyway的源码,看了半天也没找出原因,又网上找,说是重写Flyway,如:FlywayConfiguaration,没什么卵用,又找,有一篇说是依赖顺序问题,确实,这是关键点,但是加到哪呢?不知道,看日志吧,第一个报错的地方是创建RuoyiTenantAutoConfiguration的bean时报错,但是这个错和flyway一毛钱关系没有,凭直觉那就加他这吧。加了@DependsOn(“flywayConfiguaration”),还是不起作用,我靠,头都炸了,又放弃了几天。
不行,还是心里难受,又tm来回试版本,疯了,还是不行,最后冷静下来想想还是@DependsOn依赖顺序问题,这时突然又想,flyway能自动创建数据库吗?又沿这条线索查,果然,他不支持自动创建库,太操蛋了,百度后,经过改造得出如下类,得用init-sql来创建数据库,因为我从库和主库是一个库,所以init-sql只一条,如果不一样,则还需要再修改此类。
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DataSourceProperty;
import com.baomidou.dynamic.datasource.spring.boot.autoconfigure.DynamicDataSourceProperties;
import com.zaxxer.hikari.HikariDataSource;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.autoconfigure.flyway.FlywayProperties;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Map;
@Slf4j
@Component
@AllArgsConstructor
@ConditionalOnProperty(value = {"spring.flyway.enabled"})
public class DatabaseInitializer {
private final FlywayProperties flywayProperties;
//private final DataSourceProperties dataSourceProperties;
private final DynamicDataSourceProperties dataSourceProperties;
@PostConstruct
public void init() throws SQLException {
log.info("DatabaseInitializer uses flyway init-sqls to initiate database");
Map<String, DataSourceProperty> datasources = dataSourceProperties.getDatasource();
datasources.forEach((s, dataSourceProperty) -> {
try {
execEveryDb(dataSourceProperty);
} catch (SQLException e) {
e.printStackTrace();
}
});
log.info("DatabaseInitializer initialize completed");
}
private void execEveryDb(DataSourceProperty dataSourceProperty) throws SQLException {
String url = dataSourceProperty.getUrl();
// jdbc url最后一个 '/' 用于分割具体 schema?参数
int lastSplitIndex = url.lastIndexOf('?');
// 获取spring.datasource.url具体数据库schema前的jdbc url
String addressUrl = url.substring(0, lastSplitIndex);
String addresslast = url.substring(lastSplitIndex);
addressUrl = addressUrl.substring(0, addressUrl.lastIndexOf("/"));
HikariDataSource dataSource = new HikariDataSource();
dataSource.setJdbcUrl(addressUrl.concat(addresslast));
dataSource.setUsername(dataSourceProperty.getUsername());
dataSource.setPassword(dataSourceProperty.getPassword());
Connection connection = dataSource.getConnection();
Statement statement = connection.createStatement();
for (String sql : flywayProperties.getInitSqls()) {
statement.executeUpdate(sql);
}
statement.close();
connection.close();
dataSource.close();
}
}
我的yaml配置也贴一下吧
flyway:
enabled: true
baseline-on-migrate: true
url: ${spring.datasource.dynamic.datasource.master.url}
user: ${spring.datasource.dynamic.datasource.master.username}
password: ${spring.datasource.dynamic.datasource.master.password}
init-sqls:
- CREATE DATABASE IF NOT EXISTS `${spring.datasource.dynamic.datasource.master.name}` DEFAULT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
然后又回到那个第一个创建bean时报错的类,TenantAutoConfiguration,此类有和数据库操作,然后在此类上加上@DependsOn({“databaseInitializer”,“flyway”,“flywayInitializer”}),
就是在和数据库操作之前执行,创建库和表,databaseInitializer负责创建库,其它两个bean(“flyway”,"flywayInitializer"这两也是在别的文章中看到,既然是依赖顺序问题,再重写flyway有毛用)负责ddl和dml,至此,
终于
报别的错了。。。。。。。。。。
那就是sql又不符合要求,也不知道是哪不符合,凭经验来说,begin和commit,删除,全部替换,大爷的,网又不行了,还以为是哪还有问题,搞了半小时。
最后网络好了,启动,泥马,终于成了。
总结
ruoyi这个项目还是不错的,但是此项目手动的介入了加载顺序,所以导致flyway不能优先加载执行,一定要保证:flyway先执行,然后再执行其它bean的加载。
另外,
flyway不能自动 创建库,
flyway不能自动 创建库,
flyway不能自动 创建库,
flyway不能自动 创建库。
忘了说了,以上的所有东西,我是加在server模块下的。