SpringBoot基于动态数据源实现数据分库

需求背景

因产品业务需要,需使用 2 种数据库对数据进行分库存储(也可以是多个)。要求在尽量不改动原有代码的基础上实现多数据库配置和自动切换数据源。

技术选型

dynamic-datasource:dynamic-datasource-spring-boot-starter 是一个基于springboot的快速集成多数据源的启动器。其支持 Jdk 1.7+, SpringBoot 1.4.x 1.5.x 2.x.x
通过集成dynamic-datasource,仅需要在类或方法上方添加 @DS(“数据源名称”),即可实现数据源的自动切换。
框架文档https://www.kancloud.cn/tracy5546/dynamic-datasource/2264611

集成步骤

1、引入依赖

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

2、配置多数据源

spring:
  datasource:
    dynamic:
      druid:
        poolPreparedStatements: true
        maxPoolPreparedStatementPerConnectionSize: 20
      primary: system  # 默认数据源
      datasource:
        system:  # 数据源名称,可随意定义
          driver-class-name: com.mysql.cj.jdbc.Driver
          url: jdbc:mysql://******
          username: ***
          password: ******
          druid:
            validationQuery: SELECT 1 FROM DUAL
        local:  # 数据源2
          driver-class-name: org.sqlite.JDBC
          url: jdbc:sqlite:******
          username:
          password:
          druid:
            validationQuery: SELECT 'x'

3、配置SqlSessionFactory

由于业务数据源和本地数据源使用的数据库类型不同,其mapper.xml文件和所需要的拦截器等也有所不同,就需要配置两个SqlSessionFactory。那么如何随着数据源的切换,匹配到相对应的SqlSessionFactory是接下来需要考虑的问题。

实现方案:定义两个SqlSessionTemplate,分别为两个数据源的mapper指定对应的SqlSessionTemplate。这样执行到mapper接口的方法时,就会自动去对应的SqlSessionTemplate中获取SqlSessionFactory

@Configuration
// ※ 关键:使用@MapperScan注解,将Mapper接口文件和SqlSessionTemplate绑定
@MapperScan(basePackages = "com.xx.xx.*.mapper", sqlSessionTemplateRef = "systemSqlSessionTemplate")
public class DataSourceSystemConfig {

    @Bean
    public SqlSessionFactory systemSqlSessionFactory(DataSource dataSource, MyBatisProperties myBatisProperties) throws Exception {
        MybatisSqlSessionFactoryBean sessionFactoryBean = new MybatisSqlSessionFactoryBean();
        sessionFactoryBean.setDataSource(dataSource);

        //通用拦截器、类型转换器
        setMybatisSqlSessionFactoryBean(sessionFactoryBean,myBatisProperties);

        // 设置Mapper文件的扫描路径
        String mapperLocations = "classpath:mapper/system/*/*Mapper.xml";

        // 添加拦截器等组件
        sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));

        return sessionFactoryBean.getObject();
    }

    @Bean
    public SqlSessionTemplate systemSqlSessionTemplate(@Qualifier("systemSqlSessionFactory") SqlSessionFactory systemSqlSessionFactory) {
        return new SqlSessionTemplate(systemSqlSessionFactory);
    }

}
@Configuration
@MapperScan(basePackages = "com.xx.xx.*.mapper.local", sqlSessionTemplateRef = "localSqlSessionTemplate")
public class DataSourceLocalConfig {


    @Bean
    public SqlSessionFactory localSqlSessionFactory(DataSource dataSource) throws Exception {
        MybatisSqlSessionFactoryBean sessionFactoryBean = new MybatisSqlSessionFactoryBean();

        // 数据源
        sessionFactoryBean.setDataSource(dataSource);

        // 设置Mapper文件的扫描路径
        // 数据源(本地数据库已定为sqlite,所以直接指定)
        String mapperLocations = "classpath:mapper/local/*/*Mapper.xml";
        sessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver().getResources(mapperLocations));

        // 添加拦截器等组件
        setMybatisSqlSessionFactoryBean(sessionFactoryBean);
        return sessionFactoryBean.getObject();
    }

    @Bean
    public SqlSessionTemplate localSqlSessionTemplate(@Qualifier("localSqlSessionFactory") SqlSessionFactory localSqlSessionFactory) {
        return new SqlSessionTemplate(localSqlSessionFactory);
    }

}

5、编码使用

  • 在使用默认数据源时,正常编码无需手动指定数据源
  • 在使用其他数据源时,需要在方法或类上通过 @DS 注解指定数据源
  • 注解优先级:方法注解 > 类注解
  • 最佳方案:直接加在 Mapper 类上

应用场景举例:

@Service
@DS("system")  // 除指定了数据源的方法外,类中所有方法均使用system数据源
public class MyService {
    @Autowired
    private MyMapper myMapper;

    @DS("system")  //默认数据源,可以不指定
    public void methodWithDataSource1() {
        // 在此方法中使用system数据源
        myMapper.someMethod();
    }

    @DS("local")
    public void methodWithDataSource2() {
        // 在此方法中使用local数据源
        myMapper.someMethod();
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值