![](/img/trans.png)
[英]R2DBC database client not calling doOnSuccess or terminating for nested calls
[英]Database migrations with R2DBC
我是 R2DBC ( https://r2dbc.io/ ) 的新手。 我想知道r2dbc的生态系统是否有数据库迁移工具/框架。
似乎 Liquibase & Flyway 依赖于 JDBC。 是否有计划允许这些框架支持 r2dbc 驱动程序?
欢迎任何输入或反馈。
Steve 的回答是正确的,因为 R2DBC 主要是关于与实际数据的交互。 我想补充一个不同的观点。
确实,响应式 API 在迁移期间不会提供任何改进。 事实上,仔细观察,迁移是启动过程的一部分,它通常是同步的,至少在某种程度上是同步的。
需要 JDBC 进行迁移增加了这种应用程序安排的复杂性。 您需要将 JDBC 驱动程序包含到现有的 R2DBC 设置中,并且您需要配置另一个指向与 R2DBC 相同的数据库的数据库连接。 这两个要求都容易出错,因为它们需要配置为做完全相同的事情。
如今,当某个库从类路径可用时,应用程序配置框架(Spring Boot、Micronaut、Quarkus)会激活功能。 使用 JDBC 驱动程序配置引导功能,这些功能不是应用程序必需的,但在引导过程中是必需的,这有点浪费资源。
理想情况下,您可以配置一个单一的数据库连接技术,该技术可重复用于架构迁移和应用程序中以后的数据交互。
在我看来(从 R2DBC 网页的首页粗略一瞥),R2DBC 的目标确实与迁移无关。 该页面列出了以下主要功能:
没有任何内容可以保证向 Liquibase 这样的框架添加 R2DBC 支持。 当前使用的 JDBC 驱动程序不会受到使用非阻塞 API 的影响,不需要“反应式 API”,并且几乎可以肯定每个连接不需要一个以上的线程。
迁移工具主要关注数据库的形状/结构而不是内容,而 R2DBC 则针对主要关心实际数据的应用程序。
总而言之,我看不出有人会因为他们的应用程序使用 R2DBC 而不会使用像 Liquibase 这样使用 JDBC 的迁移工具的任何理由,而且我认为将 R2DBC 支持添加到像 Liquibase 这样的工具没有任何好处。
你可以试试我的包r2dbc-migrate 。
在最小配置中(假设您使用的是 Spring Boot 2.3.0.M3),只需添加
<dependency>
<groupId>name.nkonev.r2dbc-migrate</groupId>
<artifactId>r2dbc-migrate-spring-boot-starter</artifactId>
<version>0.0.24</version>
</dependency>
到 pom.xml
然后在类路径中添加 .sql 文件,例如在/db/migration/
然后加
r2dbc.migrate.resourcesPath: classpath:/db/migration/*.sql
到您的 application.yml
以上两个答案都是正确的 - 只是想补充一点,如果您正在寻找快速简便的路径并且您正在使用 maven,那么 Flyway 可能是最方便的操作方式。
您只需要 Flyway Maven 插件、两个 pom 依赖项和迁移 sql 脚本。
例如。 假设 spring - r2dbc - postgresql 您只需三个简单的步骤就可以准备好迁移基础设施:
(1) 为资源添加迁移脚本:
resources/db/migration/V1_init.sql
(2) 给pom添加两个依赖
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>
<dependency>
<groupId>org.postgresql</groupId>
<artifactId>postgresql</artifactId>
</dependency>
(3) 和构建部分中的一个插件定义:
<plugin>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-maven-plugin</artifactId>
<version>6.0.0-beta2</version>
</plugin>
现在你有一个单独的 maven CLI 命令来迁移:
mvn flyway:migrate -Dflyway.url=jdbc:postgresql://localhost:5432/test -Dflyway.user=test -Dflyway.password=test
在此处查看更多 Flyway maven 插件文档
如果有人面临同样的问题并且不想使用maven-flyway-plugin
,请查看FlywayAutoConfiguration
类。 它有@Conditional(FlywayDataSourceCondition.class)
,里面有@ConditionalOnBean(DataSource.class)
。 因此,底线是你应该提供一个非反应性的数据库环境来使 Flyway 工作。 最直接的解决方案是做这样的事情:
@Configuration
public class DataBaseConfig extends AbstractR2dbcConfiguration {
@Value("${spring.data.postgres.host}")
private String host;
@Value("${spring.data.postgres.port}")
private int port;
@Value("${spring.data.postgres.database}")
private String database;
@Value("${spring.data.postgres.username}")
private String username;
@Value("${spring.data.postgres.password}")
private String password;
@Bean
public DatabaseClient databaseClient() {
return DatabaseClient.create(connectionFactory());
}
@Bean
@Override
public PostgresqlConnectionFactory connectionFactory() {
PostgresqlConnectionConfiguration config = PostgresqlConnectionConfiguration.builder()
.host(host)
.port(port)
.database(database)
.username(username)
.password(password)
.build();
return new PostgresqlConnectionFactory(config);
}
@Bean
public DataSource dataSource() {
DataSourceBuilder dataSourceBuilder = DataSourceBuilder.create();
dataSourceBuilder.driverClassName("org.postgresql.Driver");
dataSourceBuilder.url("jdbc:postgresql://" + host + ":" + port + "/" + database);
dataSourceBuilder.username(username);
dataSourceBuilder.password(password);
return dataSourceBuilder.build();
}
}
我这样做是因为我不想:1)在每次启动时运行插件; 2)在命令行中传递数据库属性
拜托,最终有一个解决方案,至少是一个临时解决方案,因为目前还没有 Flyway 官方解决方案(我相信很快我们就会看到正式版本)。
请查看我的帖子: https : //stackoverflow.com/a/62864838/7681696
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.