方案1
Mybatis-plus 多数据源
reference
<!-- https://mvnrepository.com/artifact/com.baomidou/dynamic-datasource-spring-boot-starter -->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>dynamic-datasource-spring-boot-starter</artifactId>
<version>3.0.0</version>
</dependency>
application.yml
pring:
datasource:
#reference: https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611
dynamic:
mp-enabled: true
hikari:
maximum-pool-size: 4
minimum-idle: 2
pool-name: 'hikariPool'
connection-timeout: 6000
idle-timeout: 60000
connection-test-query: select 1
primary: master #设置默认的数据源或者数据源组,默认值即为master
strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
datasource:
master:
url: jdbc:mysql://10.50.306/db?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: ENC(F6faQmA==)
password: ENC(m1rPAzTjzmOG+elz2CQ3Nt7iRg+iYFuU)
driver-class-name: com.mysql.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
other-ds:
url: jdbc:mysql://localhost:3306/db_xxpt?serverTimezone=Asia/Shanghai&useUnicode=true&characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=true
username: root
password:
driver-class-name: com.mysql.jdbc.Driver
type: com.zaxxer.hikari.HikariDataSource
# 打印SQL语句和结果集,本地开发环境可开启,线上注释掉
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl
使用示例
public interface DSNameConstant {
/**
* 默认数据源 wms系统使用
*/
String WMS_SERVER_DEFAULT = "master";
String OTHER ="other-ds";
}
@Service
@Slf4j
public class DSDemoServiceImpl implements DSDemoService {
@Autowired
private TrustBaseInfoService trustBaseInfoService;
@Autowired
private OtherMapper oTherMapper;
@Autowired
private DynamicTestService dynamicTestService;
@Override
public void selectTest() {
try {
//默认数据源
selectWms();
// 其他数据源
/**
* mybatis-plus数据源是利用spring-aop实现的,对于aop而言它是以每次请求为单位的,
* 简单的说,虽然我们使用了两个方法,分别配置了两个@DS("),但其实第二个并不会生效
* 解决办法,对于一次请求两个数据源在把第二个数据源改为手动修改,下面的手动修改配置
* reference:https://www.cnblogs.com/drott/p/14596514.html
*/
DynamicDataSourceContextHolder.push(DSNameConstant.OTHER);
selectOther();
DynamicDataSourceContextHolder.poll();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 嵌套数据源的service中,如果操作了多个数据源,不能在最外层加上@Transaction开启事务,否则切换数据源不生效,因为这属于分布式事务了,
* 需要用seata方案解决,如果是单个数据源(不需要切换数据源)可以用@Transaction开启事务,保证每个数据源自己的完整性
*/
@Transactional
@Override
public void saveTest() {
//trustBaseInfoService.saveTrustBaseInfo()
DynamicTest dynamicTest = new DynamicTest();
dynamicTest.setName(UUID.randomUUID().toString());
dynamicTestService.save(dynamicTest);
log.info("开始saveTest insert ...");
//throw new BusinessException("测试单数据源异常事务回滚");
}
/**
* wms 数据源
* @throws Exception
*/
@DS(DSNameConstant.WMS_SERVER_DEFAULT)
public void selectWms() throws Exception {
TrustBaseInfo result = trustBaseInfoService.getTrustBaseInfoById("109");
log.info("result #### {}",result);
}
/**
* 其他数据源
*/
@DS(DSNameConstant.OTHER)
@Override
public void selectOther() {
List<Map> maps = oTherMapper.selectList();
log.info("result #### {}",maps);
}