多租戶
多個用戶間使用同一套程序,但每個用戶之間實現數據隔離
- 方法一
:在 Mapper 的自定義方法上添加註解 @SqlParser(filter = true),在查詢的時候不需要添加租戶信息
@SqlParser(filter=true)
IPage<CognitiveCardPackagePageData> selectCognitiveCardPackagePage(Page page,@Param("query") OkyaCognitiveCardPackagePageListQueryData req);
- 方法二
@Slf4j
@Configuration
@MapperScan(value = {"com.**.dao"})
public class MyBatisPlusConfig {
/**
* 分頁插件
*/
@Bean
public PaginationInterceptor paginationInterceptor(DynamicTableNameParser dynamicTableNameParser) {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
List<ISqlParser> sqlParserList = new ArrayList<>();
// 添加租戶sql解析鏈,如果是開發業務系統,可以去掉這個配置,不去也可以。
TenantSqlParser tenantSqlParser = new TenantSqlParser();
tenantSqlParser.setTenantHandler(tenantHandler());
sqlParserList.add(tenantSqlParser);
// 設置sql解析鏈
paginationInterceptor.setSqlParserList(sqlParserList);
// 設置過濾器鏈
paginationInterceptor.setSqlParserFilter(sqlParserFilter());
return paginationInterceptor;
}
@Bean
public TenantHandler tenantHandler() {
return new TenantHandler() {
@Override
public Expression getTenantId() {
// 返回當前登錄人員的租戶ID
return new LongValue(
RbacUserUtils.getCurrentTenantId());
}
@Override
public String getTenantIdColumn() {
return "tenant_id";
}
@Override
public boolean doTableFilter(String tableName) {
return false;
}
};
}
/**
* 如何有自定義無租戶的查詢,可以在此過濾
* @return SQL解析過濾
*/
@Bean
public ISqlParserFilter sqlParserFilter() {
return metaObject -> {
// 如果在程序中已經手動設置了tenant_id,此處就過濾
Object boundSql = metaObject.getValue("boundSql");
String sql = String.valueOf(ReflectionUtils
.getFieldValue(boundSql, "sql"));
return StringUtils.containsIgnoreCase(sql, "insert")
&& StringUtils.containsIgnoreCase(sql, "tenant_id");
};
}
}
注意此處的sqlParserFilter的配置,在沒有此配置之前,無論你是插入、更新、查詢,mybatis plus 就帶上tenant_id,這個tenant_id不是一直都是有的,在註冊租戶的時候就是沒有的,不過這也沒有關係,我們可以當系統當前沒有登錄的租戶時就將租戶的ID統一設置爲-1(一個統一特殊的數值),有登錄的用戶就獲取該用戶的租戶ID獲租戶自己的ID。這是沒有問題的。