问题背景:最近项目中遇到需求,既要多租户系统,同时还想指定其中一个租户下的用户为超级管理员(能够查看全平台租户数据,动态管理其中用户)
解决思路:
由于系统数据量不大, 暂不考虑性能问题
逻辑:当用户持有指定tenant_id时,SQL拼接'tenant_id LIKE %' 即可实现全平台数据查看。
实现:需要重写两个文件
1、com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor
处理SQL拼接内容,源代码如下:
@Override
public Expression buildTableExpression(final Table table, final Expression where, final String whereSegment) {
if (tenantLineHandler.ignoreTable(table.getName())) {
return null;
}
return new EqualsTo(getAliasColumn(table), tenantLineHandler.getTenantId());
}
可以看到最终是由EqualsTo完成,查看EqualsTo内容:
public EqualsTo() {
super("=");
}
无法实现LIKE拼接,此处需要自定义一个ComparisonOperator
定义位置:net.sf.jsqlparser.expression.operators.relational
内容:
public class LikeValue extends ComparisonOperator {
public LikeValue() {
super("LIKE");
}
其它部分同EqualsTo保持一致即可
2、重写TenantLineInnerInterceptor
@Override
public Expression buildTableExpression(final Table table, final Expression where, final String whereSegment) {
if (tenantLineHandler.ignoreTable(table.getName())) {
return null;
}
return new LikeValue(getAliasColumn(table), tenantLineHandler.getTenantId());
}
其它部分同TenantLineInnerInterceptor一致
3、重写net.sf.jsqlparser.expression.ExpressionVisitor,添加以下内容
void visit(LikeValue likeValue);
4、使用:在getTenantId中添加处理逻辑
@Override
public Expression getTenantId() {
String tenantId = "";//此处添加自己的tenantId获取逻辑
if (tenantId.equalsIgnoreCase("1000")) {
return new StringValue("%");
} else {
return new LongValue(tenantId);
}
}
至此,问题解决,当用户持有租户ID为1000时,返回全部数据,其它租户ID正常返回过滤后数据。