Saas多租户架构数据源切换

    技术2022-07-10  128

     

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

    独立数据库共享数据库, 独立Schema共享数据库,共享数据架构

     

    其中方案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

     

     

    使用@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");     } }

     

    动态添加数据源

     

    @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, 企业数字化建设的全景攻略

    Processed: 0.015, SQL: 9