在將項目改成多租戶模式時,因為mybatis-plus自帶的功能只會拼接left 帐萎、from和where后面的表或子查詢添加租戶id比伏。想要將selete部分的子查詢拼接租戶id,必須重寫TenantSqlParser類的processPlainSelect(PlainSelect plainSelect)方法疆导,代碼如下:
public class TestTenantSqlParser extends TenantSqlParser {
@Override
protected void processPlainSelect(PlainSelect plainSelect) {
// SELECT 至 FROM 中的嵌套查詢
List<SelectItem> selectItemList = plainSelect.getSelectItems();
for (SelectItem selectItem : selectItemList) {
if (selectItem instanceof SelectExpressionItem) {
SelectExpressionItem selectExpressionItem = (SelectExpressionItem) selectItem;
if (!(selectExpressionItem.getExpression() instanceof Column)) {
// 處理 column select 嵌套部分
operateExpression(selectExpressionItem.getExpression());
}
}
}
processPlainSelect(plainSelect, false);
}
private void operateExpression(Expression expression){
//例如:select (slect a from b where b.id=table.bid)a,table.*
//from table
if (expression instanceof SubSelect){
SubSelect subSelect = (SubSelect) expression;
PlainSelect plainSelect = (PlainSelect) subSelect.getSelectBody();
processSelectBody(plainSelect);
}
else if (expression instanceof Parenthesis){
Parenthesis parenthesis= (Parenthesis) expression;
operateExpression(parenthesis.getExpression());
}else if (expression instanceof CaseExpression) { //處理case when
CaseExpression caseExpression= (CaseExpression) expression;
caseExpression.getWhenClauses();
List<Expression> whenClauses = caseExpression.getWhenClauses();
for (Expression e : whenClauses) {
if (e instanceof WhenClause){
WhenClause whenClause= (WhenClause) e;
operateExpression(whenClause.getThenExpression());
}
}
}else if (expression instanceof Function){//處理IFNULL
Function function= (Function) expression;
if ("IFNULL".equals(function.getName())){
ExpressionList expressionList=function.getParameters();
List<Expression> ifExpression=expressionList.getExpressions();
for (Expression e:ifExpression){
operateExpression(e);
}
}
}
}
}
然后在配置文件調用
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
paginationInterceptor.setLocalPage(true);// 開啟 PageHelper 的支持
/*
* 【測試多租戶】 SQL 解析處理攔截器<br>
* 這里固定寫成住戶 1 實際情況你可以從cookie讀取赁项,因此數(shù)據(jù)看不到 【 麻花藤 】 這條記錄( 注意觀察 SQL )<br>
*/
List<ISqlParser> sqlParserList = new ArrayList<>();
/**
*此處調用重寫的類
*
*/
TestTenantSqlParser tenantSqlParser = new TestTenantSqlParser ();
tenantSqlParser.setTenantHandler(new TenantHandler() {
@Override
public Expression getTenantId() {
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 = PluginUtils.getMappedStatement(metaObject);
// 過濾自定義查詢此時無租戶信息約束【 麻花藤 】出現(xiàn)
if ("com.baomidou.springboot.mapper.UserMapper.selectListBySQL".equals(ms.getId())) {
return true;
}
return false;
}
});
return paginationInterceptor;
}