SpringBoot项目配置多数据源

前言

        之前一直没用过多数据源的方式,这次由于新领导要求,尽量少的使用fegin调用。推荐我们使用多数据源的方式。在目前的开发过程中遇到了些问题,我就顺带将配置方式和遇到的问题一起列出来。

场景

       在实际开发中,经常会遇到页面的展示数据来源于多个数据库的组合数据。为什么会发生这种情况呢?现在的主流思想就是,功能隔离,然后就因为功能拆分导致数据库也会拆分,但是部分数据又是共享的,所以要么多数据源,要么各服务之间进行调用,其实也可以去适用视图。根据功能需求,以及领导的意见吧。

代码

一、依赖

<!--多数据源-->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>

二、application.yml配置文件

spring:
  datasource:
    dynamic:
      primary: master  #这是默认数据源,必须设置
      strict: false #严格匹配数据源,默认false. true未匹配到指定数据源时抛异常,false使用默认数据源
      hikari: # 全局hikariCP参数,所有值和默认保持一致。(现已支持的参数如下,不清楚含义不要乱设置)
        minimum-idle: 5
        maximum-pool-size: 15
        connection-timeout: 30000
        auto-commit: true
        idle-timeout: 30000
        max-lifetime: 1800000
        connection-test-query: SELECT 1    
      datasource:
        master:
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://127.0.0.1:3306/db1?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true
          username: root
          password: root
        db2:
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://127.0.0.1:3306/db2?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true
          username: root
          password: giga@163.com
        db3:
          driver-class-name: com.mysql.jdbc.Driver
          url: jdbc:mysql://127.0.0.1:3306/db3?useUnicode=true&characterEncoding=utf-8&useSSL=false&rewriteBatchedStatements=true
          username: root
          password: giga@163.com

 问题一:

其中primary: master,这个是必须的,必须要设置默认数据源或者主数据源,否则会报错。

我遇到过这么一个问题:我设置primary: master,但是在启动的时候一直提示我没有设置默认数据源。烦恼了好久,然后我把后面的备注:#这是默认数据源,必须设置。这段删掉后,就没有问题了。不知道是不是因为nacos的版本问题,如果有遇到这种情况可以试着删掉试试看。

三、代码

        如果使用的是默认数据源,那就和平时的写法是一样的,该怎么处理怎么处理。我这边就不多做叙述了。如果用的是除了默认数据源以外的其他数据源的话。可以看一下下发的代码,在WasteServiceImpl的类上加上@DS("db2")或者是方法上加上@DS("db2"),其中的db2并不是数据库的名字,而是你配置文件中给他起的名字,这样就会使用该数据源了。

@DS("db2")
@Service
public class WasteServiceImpl implements WasteService {
    private  final WasteMapper wasteMapper;
    public WasteServiceImpl(WasteMapper wasteMapper) {
        this.wasteMapper = wasteMapper;
    }

    @DS("db3")
    @Override
    public List<AlarmWasteLogVo> getAlarmWasteLogList(String startDate, String endDate) {
        List<AlarmWasteLog>  alarmWasteLogList= wasteMapper.getAlarmWasteLogListByTime(startDate,endDate);
        if(CollectionUtils.isEmpty(alarmWasteLogList)){
            return null;
        }
        List<AlarmWasteLogVo> alarmWasteLogVos = Convert.toList(AlarmWasteLogVo.class, alarmWasteLogList);
        return alarmWasteLogVos;
    }
}

上图所示,当有两个@DS的时候,是谁靠的近,就是谁。那么这图中适用的数据源就是db3。

问题二:

     在我们实际开发中经常会使用到事务,当我们在某一个事务里去需要调另一个数据源的查询的时候,你会发现查询会报错说,找不到该表。这是因为在同一个事务里没有办法去切换数据源,我们需要去新开一个事务,如下图所示,这样就可以了:

@Override
    @Transactional(rollbackFor = Exception.class, propagation = Propagation.REQUIRES_NEW)
    public String getOrgIdBySysUserId(String sysUserId) {
        return lambdaQuery().select(PersonInfo::getOrgId).eq(PersonInfo::getSysUserId, sysUserId).one().getOrgId();
    }

这也就导致了同一个事务下的同一方法下,用mybatis的lambda查询时就没办法使用了。因为没有新开事务切换不了数据源。只能重新写个方法进行调用咯。没办法偷懒了。

总结

        确实在部分场景使用多数据源会比较方便,但同时部分代码也确实是重复开发了。目前遇到的情况不多,后续不知道还有没有其他问题,就先这样吧!

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值