如何确保Liquibase在R2DBC之前执行?
解决Liquibase优先执行及R2DBC-MySQL数据库缺失启动失败问题
一、确保Liquibase优先于R2DBC执行
- 调整Bean依赖关系:用Spring的话,R2DBC的连接工厂Bean默认会提前初始化,你可以给R2DBC的Bean加上
@DependsOn("liquibase")注解,强制它等Liquibase初始化完成再加载。示例代码:@Configuration public class R2dbcConfig { @Bean @DependsOn("liquibase") public ConnectionFactory connectionFactory() { return ConnectionFactories.get(ConnectionFactoryOptions.builder() .option(ConnectionFactoryOptions.DRIVER, "mysql") .option(ConnectionFactoryOptions.HOST, "localhost") .option(ConnectionFactoryOptions.PORT, 3306) .option(ConnectionFactoryOptions.DATABASE, "your_db") .option(ConnectionFactoryOptions.USER, "user") .option(ConnectionFactoryOptions.PASSWORD, "password") .build()); } } - 提前加载Liquibase配置:如果用Spring Boot,写一个自定义配置类,加上
@AutoConfigureBefore(R2dbcAutoConfiguration.class),让Liquibase的自动配置在R2DBC之前生效:@Configuration @AutoConfigureBefore(R2dbcAutoConfiguration.class) public class LiquibasePriorityConfig { // 无需额外代码,让自动配置按顺序执行即可 } - 手动触发Liquibase更新:在应用启动的最早期阶段(比如用
CommandLineRunner或者ApplicationListener)手动跑Liquibase的更新操作,确保R2DBC建立连接前完成数据库初始化。
二、解决R2DBC-MySQL无法自动创建数据库的问题
- 用JDBC预创建数据库:R2DBC-MySQL不支持自动建库,但JDBC驱动支持。你可以写一个高优先级的初始化Bean,先通过JDBC连接检查并创建目标数据库:
@Bean @Order(Ordered.HIGHEST_PRECEDENCE) public CommandLineRunner createDatabaseIfNotExists() { return args -> { try (Connection connection = DriverManager.getConnection( "jdbc:mysql://localhost:3306/?user=root&password=your_pwd", "root", "your_pwd")) { Statement stmt = connection.createStatement(); stmt.executeUpdate("CREATE DATABASE IF NOT EXISTS your_db;"); } catch (SQLException e) { // 日志记录异常即可,不用中断启动 e.printStackTrace(); } }; } - 部署脚本提前建库:在启动应用的脚本里,先执行MySQL命令创建数据库,比如:
再启动应用,这样就能保证数据库存在。mysql -u root -p"your_pwd" -e "CREATE DATABASE IF NOT EXISTS your_db;"
内容的提问来源于stack exchange,提问作者Archimedes Trajano
相关产品推荐
相关产品推荐

