实现多数据源的方式有很多种,本例采用com.baomidou(MybatisPlus拥有者旗下)包下的dynamic-datasource来实现。
1. 具体步骤
1.1 添加依赖
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>2.5.4</version>
</dependency>
1.2 配置数据源,mybatis-plus支持各种数据源的配置
配置一个默认库master,两个子库slave_1,slave_2,要注意的是如果用的mysql数据库,不需要设置driver-class-name,框架会自身自动补全这部分内容,如果用的oracle还是要去修改的。
spring:
datasource:
dynamic:
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #设置严格模式,默认false不启动. 启动后在未匹配到指定数据源时候会抛出异常,不启动则使用默认数据源.
datasource:
master:
url: jdbc:mysql://xx.xx.xx.xx:3306/dynamic
username: root
password: 123456
driver-class-name: com.mysql.jdbc.Driver # 3.2.0开始支持SPI可省略此配置
slave_1:
driver-class-name: oracle.jdbc.OracleDriver
url: jdbc:oracle:thin:@192.168.7.88:1521:db
username: test
password: test
#Oracle需要打开注释
validation-query: SELECT 1 FROM DUAL
slave_2:
url: ENC(xxxxx) # 内置加密,使用请查看详细文档
username: ENC(xxxxx)
password: ENC(xxxxx)
driver-class-name: com.mysql.jdbc.Driver
schema: db/schema.sql # 配置则生效,自动初始化表结构
data: db/data.sql # 配置则生效,自动初始化数据
continue-on-error: true # 默认true,初始化失败是否继续
separator: ";" # sql默认分号分隔符
1.3 通过注解方式注解到类或者方法上
项目中使用@DS注解来切换数据源,@DS使用需要注意的几点:
- @DS(注解不能直接用于mapper类上只能用在service层的类或方法上
- @DS可以注解在方法或类上,同时存在使用就近原则,方法上注解优于类上注解
- @DS和@Transactional(rollbackFor = Exception.class)不要同时使用,会导致切换数据源失效
@Service("LdService")
@DS("slave_1")
public class LdServiceImpl implements LdService {
}
也可使用DynamicDataSourceContextHolder.push(dsKey);方法来切换数据源,dsKey:你自己要切换的数据源名称,和@DS括号中的一样
2.切换数据源失效场景
(1)@DS中写的是错误的数据源符号,如oracle写成了orcale,虽然一个字符之差,而且也很难察觉,这样如果配置了默认数据源则会使用默认的数据源,否则会抛出异常。
(2)@DS和@Transactional(rollbackFor = Exception.class)不要同时使用,若同时使用会将数据源直接交给spring来管理,
这也是切换数据源经常失效场景之一,若需要使用事务,则要考虑分布式事务,常用的分布式事务框架有Seata、TX-LCN等等 。注意:其他多数据源的方法也是如此。
(3)方法内部的相互调用,如:
public UserService {
@DS("first")
public void test1() {
// do something
test2();
}
@DS("second")
public void test2() {
// do something
}
}
部调用 userservice.test1() 在执行到 test2()中的时候也是不能切换数据源的,解决方式为把test2()方法提到另外一个service,单独调用
网友评论