Saas多租户架构数据源切换
一.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, 企业数字化建设的全景攻略