多租户 SQL 解析器
- 这里配合 分页拦截器 使用, spring boot 例子配置如下:
示例工程:
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
/*
* 【测试多租户】 SQL 解析处理拦截器<br>
* 这里固定写成住户 1 实际情况你可以从cookie读取,因此数据看不到 【 麻花藤 】 这条记录( 注意观察 SQL )<br>
*/
List<ISqlParser> sqlParserList = new ArrayList<>();
TenantSqlParser tenantSqlParser = new TenantSqlParser();
tenantSqlParser.setTenantHandler(new TenantHandler() {
@Override
public Expression getTenantId(boolean where) {
// 该 where 条件 3.2.0 版本开始添加的,用于分区是否为在 where 条件中使用
// 如果是in/between之类的多个tenantId的情况,参考下方示例
return new LongValue(1L);
}
@Override
public String getTenantIdColumn() {
return "tenant_id";
}
@Override
public boolean doTableFilter(String tableName) {
// 这里可以判断是否过滤表
/*
if ("user".equals(tableName)) {
return true;
}*/
return false;
}
});
sqlParserList.add(tenantSqlParser);
paginationInterceptor.setSqlParserList(sqlParserList);
paginationInterceptor.setSqlParserFilter(new ISqlParserFilter() {
@Override
public boolean doFilter(MetaObject metaObject) {
MappedStatement ms = SqlParserHelper.getMappedStatement(metaObject);
// 过滤自定义查询此时无租户信息约束【 麻花藤 】出现
if ("com.baomidou.springboot.mapper.UserMapper.selectListBySQL".equals(ms.getId())) {
return true;
}
return false;
}
});
return paginationInterceptor;
}
- 关于多租户实现条件tenant_id in (1,2,3)的解决方案
核心代码: MybatisPlusConfig
/**
* 2019-8-1
*
* https://gitee.com/baomidou/mybatis-plus/issues/IZZ3M
*
* 参考示例:
* https://gitee.com/baomidou/mybatis-plus-samples/tree/master/mybatis-plus-sample-tenant
*
* tenant_id in (1,2)
*
* @return
*/
@Override
public Expression getTenantId(boolean where) {
//如果是where,可以追加多租户多个条件in,不是where的情况:比如当insert时,不能insert into user(name, tenant_id) values('test', tenant_id IN (1, 2));
final boolean multipleTenantIds = true;//自己判断是单个tenantId还是需要多个id in(1,2,3)
if (where && multipleTenantIds) {
//演示如何实现tenant_id in (1,2)
return multipleTenantIdCondition();
} else {
//演示:tenant_id=1
return singleTenantIdCondition();
}
}
private Expression singleTenantIdCondition() {
return new LongValue(1);//ID自己想办法获取到
}
private Expression multipleTenantIdCondition() {
final InExpression inExpression = new InExpression();
inExpression.setLeftExpression(new Column(getTenantIdColumn()));
final ExpressionList itemsList = new ExpressionList();
final List<Expression> inValues = new ArrayList<>(2);
inValues.add(new LongValue(1));//ID自己想办法获取到
inValues.add(new LongValue(2));
itemsList.setExpressions(inValues);
inExpression.setRightItemsList(itemsList);
return inExpression;
}
public class MyTenantParser extends TenantSqlParser {
//目前这种情况比较小众,自己定制可以参考
//参考 https://gitee.com/baomidou/mybatis-plus-samples/blob/master/mybatis-plus-sample-tenant/src/main/java/com/baomidou/mybatisplus/samples/tenant/config/MyTenantParser.java
}
- 相关 SQL 解析如多租户可通过
@SqlParser(filter=true)
排除 SQL 解析,注意!!全局配置 sqlParserCache 设置为 true 才生效。(3.1.1开始不再需要这一步)
# 开启 SQL 解析缓存注解生效
mybatis-plus:
global-config:
sql-parser-cache: true
当前内容版权归 MyBatis-Plus 或其关联方所有,如需对内容或内容相关联开源项目进行关注与资助,请访问 MyBatis-Plus .