Saas多租户架构数据源切换

一.Saas多租户在数据存储上有三种主要的方案:

  1. 独立数据库
  2. 共享数据库, 独立Schema
  3. 共享数据库,共享数据架构

 

其中方案1和方案2要解决的核心问题就是租户识别,需要在应用层实现数据源的动态切换,根据租户标识动态的将用户请求路由到对应的租户数据源。

 

二.利用Mybatis-Plus实现动态数据源切换

MyBatis-Plus是一个 MyBatis 的增强工具,在 MyBatis 的基础上只做增强不做改变,为简化开发、提高效率而生。

 

1.添加相关依赖:

<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>druid-spring-boot-starter</artifactId>
    <version>1.1.21</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.1.0</version>
</dependency>
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>dynamic-datasource-spring-boot-starter</artifactId>
    <version>2.5.4</version>
</dependency>

2.配置数据源

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
        slave_1:
          url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver
        slave_2:
          url: jdbc:mysql://xx.xx.xx.xx:3307/dynamic
          username: root
          password: 123456
          driver-class-name: com.mysql.jdbc.Driver

        #......省略
        #以上会配置一个默认库master,一个组slave下有两个子库slave_1,slave_2
  1. 使用@DS切换数据源

 

@DS 可以注解在方法上和类上,同时存在方法注解优先于类上注解。

强烈建议只注解在service实现上。

 

 

注解

结果

没有@DS

默认数据源

@DS("dsName")

dsName可以为组名也可以为具体某个库的名称

 

@Service
@DS("slave")
public class UserServiceImpl implements UserService {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    public List<Map<String, Object>> selectAll() {
        return  jdbcTemplate.queryForList("select * from user");
    }

    @Override
    @DS("slave_1")
    public List<Map<String, Object>> selectByCondition() {
        return  jdbcTemplate.queryForList("select * from user where age >10");
    }
}

 

  1. 动态添加数据源
@Autowired
DynamicRoutingDataSource dynamicRoutingDataSource;
@Autowired
DynamicDataSourceCreator dynamicDataSourceCreator;


public void addDataSource(DataSourceInfo dataSourceInfo){

    DataSourceProperty dataSourceProperty = new DataSourceProperty();
    String pollName = dataSourceInfo.getPollName();
    dataSourceProperty.setPollName(pollName);
    String driverClassName = dataSourceInfo.getDriverClassName();
    dataSourceProperty.setDriverClassName(driverClassName);
    String url = dataSourceInfo.getUrl();
    dataSourceProperty.setUrl(url);
    String username = dataSourceInfo.getUsername();
    String password = dataSourceInfo.getPassword();
    dataSourceProperty.setUsername(username);
    dataSourceProperty.setPassword(password);

    DataSource ds = dynamicDataSourceCreator.createDruidDataSource(dataSourceProperty);

    dynamicRoutingDataSource.addDataSource(pollName, ds);

}

 

    总结:可见使用Mybatis-Plus来实现Saas多租户数据源切换是非常简单的,只需要很少的配置和注解就可以搞定,对业务代码的侵入非常小。

 

    我在开发狐小E的时候也遇到了动态切换数据源的问题,在此记录一下。

 

   狐小E, 企业数字化建设的全景攻略

posted @ 2020-07-01 08:53  九尾狐0813  阅读(1271)  评论(0编辑  收藏  举报