R2dbc配置多数据源问题
根据官网配置r2dbc 连接mysql多数据源所遇到的问题
pom配置可以参考官网,
不过我这样配置会报错 我并没有这样配置
将以下内容添加到 pom.xml 文件dependencies元素:
<dependencyManagement>
<dependencies>
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-bom</artifactId>
<version>${r2dbc-releasetrain.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- other dependency elements omitted -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-r2dbc</artifactId>
<version>1.3.3</version>
</dependency>
<!-- a R2DBC driver -->
<dependency>
<groupId>io.r2dbc</groupId>
<artifactId>r2dbc-h2</artifactId>
<version>Arabba-SR10</version>
</dependency>
</dependencies>
将 pom.xml 中 Spring 的版本改为
<spring-framework.version>5.3.9</spring-framework.version>
将 Maven 的 Spring Milestone 存储库的以下位置添加到您的位置pom.xml,使其与您的元素处于同一级别:
<repositories>
<repository>
<id>spring-milestone</id>
<name>Spring Maven MILESTONE Repository</name>
<url>https://repo.spring.io/libs-milestone</url>
</repository>
</repositories>
以下是官网原话
当使用多个可能不同的数据库时,您的应用程序将需要不同的配置方法。所提供的AbstractR2dbcConfiguration支持类假定单个ConnectionFactory从中Dialect得到的。话虽如此,您需要自己定义一些 bean 来配置 Spring Data R2DBC 以处理多个数据库。
R2DBC 存储库需要R2dbcEntityOperations实现存储库。无需使用即可扫描存储库的简单配置AbstractR2dbcConfiguration如下所示:
但是有一个问题 官方的这个显示返回的类型是一个Operations 是他的接口 导致spring无法注入这个对象 不知道是bug还是版本问题。会出现
Cannot determine database’s type as ConnectionFactory is not options-capable
无法确定数据库的类型,因为ConnectionFactory不支持选项
所以我们将返回类型改为R2dbcEntityTemplate 即可
@Configuration
@EnableR2dbcRepositories(basePackages = "com.acme.mysql", entityOperationsRef = "mysqlR2dbcEntityOperations")
static class MySQLConfiguration {
@Bean
@Qualifier("mysql")
public ConnectionFactory mysqlConnectionFactory() {
return …
}
@Bean
public R2dbcEntityTemplate mysqlR2dbcEntityOperations(@Qualifier("mysql") ConnectionFactory connectionFactory) {
DatabaseClient databaseClient = DatabaseClient.create(connectionFactory);
return new R2dbcEntityTemplate(databaseClient, MySqlDialect.INSTANCE);
}
}
这样我们就可以灵活的切换数据源了
例如:
cofig配置文件
@Configuration
@EnableR2dbcRepositories(basePackages = "webflux.demo", entityOperationsRef = "mysqlR2dbcEntityOperations")
public class config {
@Bean("mysql")
public ConnectionFactory mysqlConnectionFactory() {
ConnectionFactoryOptions options = builder()
.option(DRIVER, "mysql")
.option(HOST, "")
.option(PORT, 3306)
.option(USER, "")
.option(PASSWORD, "")
.option(SSL, false)
.option(DATABASE, "nlp")
.build();
ConnectionFactory connectionFactory = ConnectionFactories.get(options);
return connectionFactory;
}
@Bean("ecs")
public ConnectionFactory mysqlConnectionFactory1(){
ConnectionFactoryOptions options = builder()
.option(DRIVER, "mysql")
.option(HOST, "")
.option(PORT, 3306)
.option(USER, "")
.option(PASSWORD, "")
.option(SSL, false)
.option(DATABASE, "r2dbc")
.build();
ConnectionFactory connectionFactory = ConnectionFactories.get(options);
return connectionFactory;
}
@Bean("nlp")
public R2dbcEntityTemplate mysqlR2dbcEntityOperations(@Qualifier("mysql") ConnectionFactory connectionFactory) {
DatabaseClient databaseClient = DatabaseClient.create(connectionFactory);
return new R2dbcEntityTemplate(databaseClient, MySqlDialect.INSTANCE);
}
@Bean("r2dbc")
public R2dbcEntityTemplate mysqlR2dbcEntityOperations1(@Qualifier("ecs") ConnectionFactory connectionFactory) {
DatabaseClient databaseClient = DatabaseClient.create(connectionFactory);
return new R2dbcEntityTemplate(databaseClient, MySqlDialect.INSTANCE);
}
}
测试
我们用Qualifier指定哪个数据源 然后就可以使用
@RestController
@RequestMapping("/demo")
public class DemoController {
@Autowired
@Qualifier("nlp")
R2dbcEntityTemplate nlp;
@Autowired
@Qualifier("r2dbc")
R2dbcEntityTemplate user;
@RequestMapping("/a")
public Mono<List<User>> a() throws InterruptedException {
Mono<List<User>> listMono = user.select(User.class).all().collectList();
return listMono;
}
@RequestMapping("/cc")
public Mono<Video> aaa() {
Mono<Video> one = nlp.select(Video.class).from("video")
.matching(Query.query(Criteria.where("video_id").is("37"))).one();
return one;
}
}
测试结果
以下是2个不同的数据库