配置
租户解析器处理程序
import com.baomidou.mybatisplus.extension.plugins.tenant.TenantSqlParser;
import net.sf.jsqlparser.expression.BinaryExpression;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.Parenthesis;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
import net.sf.jsqlparser.expression.operators.relational.*;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.schema.Table;
import net.sf.jsqlparser.statement.select.*;
import java.util.List;
public class MpTenantParserHandler extends TenantSqlParser {
protected Expression processTableAlias(Expression expression, Table table) {
String tableAliasName;
if (table.getAlias() == null) {
tableAliasName = table.getName();
} else {
tableAliasName = table.getAlias().getName();
}
if (expression instanceof InExpression) {
InExpression in = (InExpression) expression;
if (in.getLeftExpression() instanceof Column) {
setTableAliasNameForColumn((Column) in.getLeftExpression(), tableAliasName);
}
} else if (expression instanceof BinaryExpression) {
BinaryExpression compare = (BinaryExpression) expression;
if (compare.getLeftExpression() instanceof Column) {
setTableAliasNameForColumn((Column) compare.getLeftExpression(), tableAliasName);
} else if (compare.getRightExpression() instanceof Column) {
setTableAliasNameForColumn((Column) compare.getRightExpression(), tableAliasName);
}
} else if (expression instanceof Between) {
Between between = (Between) expression;
if (between.getLeftExpression() instanceof Column) {
setTableAliasNameForColumn((Column) between.getLeftExpression(), tableAliasName);
}
}
return expression;
}
private void setTableAliasNameForColumn(Column column, String tableAliasName) {
column.setColumnName(tableAliasName + "." + column.getColumnName());
}
@Override
protected Expression builderExpression(Expression currentExpression, Table table) {
final Expression tenantExpression = this.getTenantHandler().getTenantId(true);
Expression appendExpression;
if (!(tenantExpression instanceof SupportsOldOracleJoinSyntax)) {
appendExpression = new EqualsTo();
((EqualsTo) appendExpression).setLeftExpression(this.getAliasColumn(table));
((EqualsTo) appendExpression).setRightExpression(tenantExpression);
} else {
appendExpression = processTableAlias(tenantExpression, table);
}
if (currentExpression == null) {
return appendExpression;
}
if (currentExpression instanceof BinaryExpression) {
BinaryExpression binaryExpression = (BinaryExpression) currentExpression;
if (binaryExpression.getLeftExpression() instanceof FromItem) {
processFromItem((FromItem) binaryExpression.getLeftExpression());
}
if (binaryExpression.getRightExpression() instanceof FromItem) {
processFromItem((FromItem) binaryExpression.getRightExpression());
}
} else if (currentExpression instanceof InExpression) {
InExpression inExp = (InExpression) currentExpression;
ItemsList rightItems = inExp.getRightItemsList();
if (rightItems instanceof SubSelect) {
processSelectBody(((SubSelect) rightItems).getSelectBody());
}
}
if (currentExpression instanceof OrExpression) {
return new AndExpression(new Parenthesis(currentExpression), appendExpression);
} else {
return new AndExpression(currentExpression, appendExpression);
}
}
@Override
protected void processPlainSelect(PlainSelect plainSelect, boolean addColumn) {
FromItem fromItem = plainSelect.getFromItem();
if (fromItem instanceof Table) {
Table fromTable = (Table) fromItem;
if (!this.getTenantHandler().doTableFilter(fromTable.getName())) {
plainSelect.setWhere(builderExpression(plainSelect.getWhere(), fromTable));
if (addColumn) {
plainSelect.getSelectItems().add(new SelectExpressionItem(new Column(this.getTenantHandler().getTenantIdColumn())));
}
}
} else {
processFromItem(fromItem);
}
List joins = plainSelect.getJoins();
if (joins != null && joins.size() > 0) {
joins.forEach(j -> {
processJoin(j);
processFromItem(j.getRightItem());
});
}
}
}
租户处理器
@Component
@AllArgsConstructor
public class MpTenantHandler implements TenantHandler {
private final HeaderHolder headerHolder;
@Override
public Expression getTenantId(boolean where) {
Long tid = headerHolder.findTid();
return new LongValue(tid);
}
@Override
public String getTenantIdColumn() {
return "tid";
}
@Override
public boolean doTableFilter(String tableName) {
//TODO 如果是超级租户 不进行过滤
return Objects.equals(headerHolder.getTid(), 1L);
}
}
MP配置
@Configuration
public class MybatisPlusConfig {
@Bean
public PaginationInterceptor paginationInterceptor(MpTenantHandler mpTenantHandler) {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
List sqlParserList = new ArrayList<>();
TenantSqlParser tenantSqlParser = new MpTenantParserHandler();
// 解析处理拦截器
tenantSqlParser.setTenantHandler(mpTenantHandler);
sqlParserList.add(tenantSqlParser);
paginationInterceptor.setSqlParserList(sqlParserList);
return paginationInterceptor;
}
}
租户字段处理
public class BaseEntity {
@TableField(insertStrategy = FieldStrategy.NEVER,
updateStrategy = FieldStrategy.NEVER)
private Long tid;
}
插入和更新时租户字段由租户处理器接管,mp自带的增删改查不再有租户字段
查询
插入
@Override
public void processInsert(Insert insert) {
if (tenantHandler.doTableFilter(insert.getTable().getName())) {
// 过滤退出执行
return;
}
insert.getColumns().add(new Column(tenantHandler.getTenantIdColumn()));
if (insert.getSelect() != null) {
processPlainSelect((PlainSelect) insert.getSelect().getSelectBody(), true);
} else if (insert.getItemsList() != null) {
// fixed github pull/295
ItemsList itemsList = insert.getItemsList();
if (itemsList instanceof MultiExpressionList) {
((MultiExpressionList) itemsList).getExprList().forEach(el -> el.getExpressions().add(tenantHandler.getTenantId(false)));
} else {
((ExpressionList) insert.getItemsList()).getExpressions().add(tenantHandler.getTenantId(false));
}
} else {
throw ExceptionUtils.mpe("Failed to process multiple-table update, please exclude the tableName or statementId");
}
}
更新
@Override
public void processUpdate(Update update) {
final Table table = update.getTable();
if (tenantHandler.doTableFilter(table.getName())) {
// 过滤退出执行
return;
}
update.setWhere(this.andExpression(table, update.getWhere()));
}
删除
@Override
public void processDelete(Delete delete) {
if (tenantHandler.doTableFilter(delete.getTable().getName())) {
// 过滤退出执行
return;
}
delete.setWhere(this.andExpression(delete.getTable(), delete.getWhere()));
}