随着业务变得复杂,单个数据源无法满足项目的需要了,因此有的时候需要配置多个数据源。
除了通过自定义配置类实现多数据源的方式,这里更加推荐使用dynamic-datasource
这款插件实现多数据源配置。
这里,我使用Spring Boot + MyBatis-Plus为例分享一下多数据源配置和操作,以下内容对于Spring Boot + MyBatis也是完全适用的。
1,添加依赖
在pom.xml
中加入以下依赖引入dynamic-datasource
包:
<!-- dynamic-datasource多数据源支持 -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.6.1</version>
</dependency>
可以在其Maven仓库查看最新版本号。
2,配置多数据源
在Spring Boot配置文件中加入以下多数据源配置:
spring:
# 多数据源
datasource:
dynamic:
# 设置主数据源为master
primary: master
datasource:
# 配置数据源master
master:
url: jdbc:mysql://127.0.0.1:3306/cat_catentity
username: swsk33
password: dev-2333
# 配置数据源slave-1
slave-1:
url: jdbc:mysql://127.0.0.1:3306/cat_comment
username: swsk33
password: dev-2333
可见这里定义了两个数据源,上述关键配置意义如下:
spring.datasource.dynamic.primary
设置主数据源名字,这里设置为master
,这一项可以不配置,不配置默认就是master
spring.datasource.dynamic.datasource
在这一项下面就是配置每一个数据源了,可见这里我配置了两个数据源,名字分别是master
和slave-1
(名字可以自定义),并分别配置了两者的地址url
、用户名username
和密码password
由于这里所有的数据源都是使用的MySQL数据库,因此引入mysql-driver
后就不需要写驱动名了,如果说要配置多个不同数据库的数据源就要指定每个数据源的驱动:
spring:
# 多数据源
datasource:
dynamic:
# 设置主数据源为mysql
primary: mysql
datasource:
# 配置数据源mysql
mysql:
url: jdbc:mysql://127.0.0.1:3306/cat_catentity
username: swsk33
password: dev-2333
# 指定MySQL的驱动类
driver-class-name: com.mysql.jdbc.Driver
# 配置数据源postgre
postgre:
url: jdbc:postgresql://127.0.0.1:3306/cat_comment
username: swsk33
password: dev-2333
# 指定PostgreSQL的驱动类
driver-class-name: org.postgresql.Driver
3,在代码中动态地切换数据源
配置完成后,切换数据源就非常简单了!通过@DS
注解即可。
@DS
可以注解在方法上或类上,遵循就近原则,方法上注解优先于类上注解。
注解 | 结果 |
---|---|
没有@DS |
默认数据源 |
@DS("dsName") |
dsName 可以为组名也可以为具体某个库的名称 |
通常,@DS
可以用于以下位置切换数据源。
(1) 在DAO
层
在DAO
层的类或者方法上标注@DS
就可以达到切换数据源的目的:
@Mapper
public interface CatDAO extends BaseMapper<Cat> {
@DS("salve-1")
@Insert("insert into `xxx` ...")
int insert(Comment comment);
}
例如上述这个DAO
类,其中我定义了个insert
方法,并标注了@DS("slave-1")
,那么服务层或者其它类调用这个方法时,就是对配置文件中名为slave-1
的数据源进行操作。
这个DAO
继承了MyBatis-Plus的BaseMapper
类,那么在这里调用MyBatis-Plus中的方法例如selectById
等等,则是对配置文件中默认数据源master
进行操作。
这也说明了:没有标注@DS
的方法就是对默认数据源操作,标注了的方法就是对注解中指定的数据源进行操作。
与此同时,如果不对DAO
中的方法标注而是直接对DAO
中的类进行标注,那么这个类中的方法都是会对注解中指定的数据源进行操作。
(2) 在Service
实现层
假设现在不对DAO
层的任何地方标注@DS
,而是在Service
中进行标注也是可以的,例如:
@Component
public class CatServiceImpl implements CatService {
@Autowired
private CatDAO catDAO;
@Override
public Cat getCatById(int id) {
...
}
@Override
@DS("slave-1")
public Comment getCommentById(int id) {
...
}
}
那么由于getCommentById
方法标注了@DS("slave-1")
,所以调用该方法时是对slave-1
数据源进行操作,没有标注的则是对默认数据源进行操作。
同样地也可以将@DS
标注在类上面。
这里有一个小坑:如果说方法A
上面标注了@DS("slave-1")
而方法B
没有标注@DS
,那么在方法B
中调用方法A
,我们调用方法B
,是对哪个数据源进行操作呢?
答案是对配置文件中主数据源进行操作。
因为我们最终调用的是方法B
,其遵循就近原则,因此最终就是按照方法B
的标准为准,方法B
没有标注@DS
,因此仍然是对主数据源进行操作。