Springcloud+Mybatis使用多数据源的四种方式

本文详细介绍了Springcloud+Mybatis使用多数据源的四种方式:分包方式、参数化切换、注解+AOP和动态添加。重点讨论了每种方式的实现原理、优缺点以及代码实现,包括数据源配置、切换逻辑和事务处理。同时,文章还提到了动态添加数据源的业务场景和实现思路。
摘要由CSDN通过智能技术生成

Springcloud+Mybatis使用多数据源的四种方式

前段时间在做会员中心和中间件系统开发时,多次碰到多数据源配置问题,主要用到分包方式、参数化切换、注解+AOP、动态添加 这四种方式。这里做一下总结,分享下使用心得以及踩过的坑。

分包方式

数据源配置文件

在yml中,配置两个数据源,id分别为master和s1。

spring:
  datasource:
    master:
      jdbcUrl: jdbc:mysql://192.168.xxx.xxx:xxxx/db1?.........
      username: xxx
      password: xxx
      driverClassName: com.mysql.cj.jdbc.Driver
    s1:
      jdbcUrl: jdbc:mysql://192.168.xxx.xxx:xxxx/db2?........
      username: xxx
      password: xxx
      driverClassName: com.mysql.cj.jdbc.Driver
复制代码

数据源配置类

master数据源配置类

注意点:

需要用@Primary注解指定默认数据源,否则spring不知道哪个是主数据源;

@Configuration
@MapperScan(basePackages = "com.hosjoy.xxx.xxx.xxx.xxx.mapper.master", sqlSessionFactoryRef = "masterSqlSessionFactory")
public class MasterDataSourceConfig {

    //默认数据源
    @Bean(name = "masterDataSource")
    @Primary
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public HikariDataSource masterDataSource() {
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

    @Bean(name = "masterSqlSessionFactory")
    @Primary
    public SqlSessionFactory masterSqlSessionFactory(@Qualifier("masterDataSource") DataSource datasource, PaginationInterceptor paginationInterceptor)
            throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(datasource);
        bean.setMapperLocations(
                // 设置mybatis的xml所在位置
                new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/master/**/**.xml"));
        bean.setPlugins(new Interceptor[]{paginationInterceptor});
        return bean.getObject();
    }

    @Bean(name = "masterSqlSessionTemplate")
    @Primary
    public SqlSessionTemplate masterSqlSessionTemplate(
            @Qualifier("masterSqlSessionFactory") SqlSessionFactory sessionfactory) {
        return new SqlSessionTemplate(sessionfactory);
    }
}
复制代码

s1数据源配置类

@Configuration
@MapperScan(basePackages = "com.hosjoy.xxx.xxx.xxx.xxx.mapper.s1", sqlSessionFactoryRef = "s1SqlSessionFactory")
public class S1DataSourceConfig {

    @Bean(name = "s1DataSource")
    @ConfigurationProperties(prefix = "spring.datasource.s1")
    public HikariDataSource s1DataSource() {
        return DataSourceBuilder.create().type(HikariDataSource.class).build();
    }

    @Bean(name = "s1SqlSessionFactory")
    public SqlSessionFactory s1SqlSessionFactory(@Qualifier("s1DataSource") DataSource datasource
            , PaginationInterceptor paginationInterceptor)
            throws Exception {
        MybatisSqlSessionFactoryBean bean = new MybatisSqlSessionFactoryBean();
        bean.setDataSource(datasource);
        bean.setMapperLocations(
                // 设置mybatis的xml所在位置
                new PathMatchingResourcePatternResolver().getResources("classpath*:mapper/s1/**/**.xml"));
        bean.setPlugins(new Interceptor[]{paginationInterceptor});
        return bean.getObject();
    }

    @Bean(name = "s1SqlSessionTemplate")
    public SqlSessionTemplate s1SqlSessionTemplate(
            @Qualifier("s1SqlSessionFactory") SqlSessionFactory sessionfactory) {
        return new SqlSessionTemplate(sessionfactory);
    }
}
复制代码

使用

可以看出,mapper接口、xml文件,需要按照不同的数据源分包。在操作数据库时,根据需要在service类中注入dao层。

特点分析

优点

实现起来简单,只需要编写数据源配置文件和配置类,mapper接口和xml文件注意分包即可。

缺点

很明显,如果后面要增加或删除数据源,不仅要修改数据源配置文件,还需要修改配置类。

例如增加一个数据源,同时还需要新写一个该数据源的配置类,同时还要考虑新建mapper接口包、xml包等,没有实现 “热插拔” 效果。

参数化切换方式

思想

参数化切换数据源,意思是,业务侧需要根据当前业务参数,动态的切换到不同的数据源。

这与分包思想不同。分包的前提是在编写代码的时候,就已经知道当前需要用哪个数据源,而参数化切换数据源需要根据业务参数决定用哪个数据源。

例如,请求参数userType值为1时,需要切换到数据源slave1;请求参数userType值为2时,需要切换到数据源slave2。

/**伪代码**/
int userType = reqUser.getType();
if (userType == 1){
    //切换到数据源slave1
    //数据库操作
} else if(userType == 2){
    //切换到数据源slave2
    //数据库操作
}
复制代码

设计思路

数据源注册

数据源配置类创建datasource时,从yml配置文件中读取所有数据源配置,自动创建每个数据源,并注册至bean工厂和AbstractRoutingDatasource(后面聊聊这个),同时返回默认的数据源master。

 

image-20200701112808482

 

 

数据源切换

(1)通过线程池处理请求,每个请求独占一个线程,这样每个线程切换数据源时互不影响。

(2)根据业务参数获取应切换的数据源ID,根据ID从数据源缓存池获取数据源bean;

(3)生成当前线程数据源key;

(4)将key设置到threadLocal;

(5)将key和数据源bean放入数据源缓存池;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值