R2dbc配置多数据源问题
根据官网配置r2dbc 连接mysql多数据源所遇到的问题
pom配置可以参考官网,
不过我这样配置会报错 我并没有这样配置
将以下内容添加到 pom.xml 文件dependencies元素:
io.r2dbcr2dbc-bom${r2dbc-releasetrain.version}pomimport
org.springframework.dataspring-data-r2dbc1.3.3io.r2dbcr2dbc-h2Arabba-SR10
将 pom.xml 中 Spring 的版本改为
5.3.9
将 Maven 的 Spring Milestone 存储库的以下位置添加到您的位置pom.xml,使其与您的元素处于同一级别:
spring-milestoneSpring Maven MILESTONE Repositoryhttps://repo.spring.io/libs-milestone
以下是官网原话
当使用多个可能不同的数据库时,您的应用程序将需要不同的配置方法。所提供的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 …}@Beanpublic 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 {&#64;Autowired&#64;Qualifier("nlp")R2dbcEntityTemplate nlp;&#64;Autowired&#64;Qualifier("r2dbc")R2dbcEntityTemplate user;&#64;RequestMapping("/a")public Mono<List<User>> a() throws InterruptedException {Mono<List<User>> listMono &#61; user.select(User.class).all().collectList();return listMono;} &#64;RequestMapping("/cc")public Mono<Video> aaa() {Mono<Video> one &#61; nlp.select(Video.class).from("video").matching(Query.query(Criteria.where("video_id").is("37"))).one();return one;}
}
测试结果
以下是2个不同的数据库