场景描述:
前一阵子接手的新项目中需要使用2个数据源。
一个叫行云数据库,一个叫OceanBase数据库。
就是说,我有时候查询要查行云的数据,有时候查询要查 OceanBase 的数据,咋办?
废话不多说, 下面以mysql为例,开整。
一、环境依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.3.0</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.28</version>
</dependency>
二、实现思路
在进行下一步之前,我们必须要知道 SpringBoot 自动配置的相关原理,因为之前,我们大多是单数据源。
# 配置mysql数据库
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/blog?serverTimezone=Asia/Shanghai&allowMultiQueries=true
username: root
password: root
从前只是会用,会配置,甚至都是别人给配置的自己直接拿来用。
但是要搞懂动态数据源就必须要先搞懂自动配置。
现在我们要实现多数据源,并且可以自动切换。
也就是我 A 查询连接的是行云数据库。
而我 B 查询却连接的是 OceanBase 数据库。
怎么办?
那第一个肯定就不能再使用DataSourceAutoConfigurtation了。
我直接反手一个 exclude 。
@EnableAutoConfiguration(exclude = {
DataSourceAutoConfiguration.class})
然后呢?
Spring boot想得很周到,它提供了AbstractRoutingDataSource 抽象类。
这个类能根据用户定义的规则选择当前的数据源。
有同学要问了:
AbstractRoutingDataSource 是什么东西?
AbstractRoutingDataSource 是一个抽象类。
它继承了 AbstractDataSource 抽象类。
而 AbstractDataSource 实现了 DataSource 接口。
也就是说:AbstractRoutingDataSource 他实际上就是一个DataSource 。
AbstractRoutingDataSource 中有两个关键方法。
setTargetDataSources(Map<Object, Object> targetDataSources)
第一个方法见名知意,设置目标数据源(复数也就是多个)。
protected abstract Object determineCurrentLookupKey();
第二个方法是仅有的一个抽象方法,需要开发者具体实现,也可以见名知意,决定当前使用(目标数据源中的)哪个。
我们要做的是什么?
我们准备 2 个数据源,全部配置好放进 Map<Object, Object> targetDataSources