一.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, 企業數字化建設的全景攻略