在將項(xiàng)目改成多租戶模式時(shí),因?yàn)閙ybatis-plus自帶的功能只會(huì)拼接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){
? ? ? ? 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);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }
}
然后在配置文件調(diào)用
@Bean
public PaginationInterceptor paginationInterceptor() {
? ? PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
? ? paginationInterceptor.setLocalPage(true);// 開啟 PageHelper 的支持
? ? /*
? ? * 【測(cè)試多租戶】 SQL 解析處理攔截器<br>
? ? * 這里固定寫成住戶 1 實(shí)際情況你可以從cookie讀取,因此數(shù)據(jù)看不到 【 麻花藤 】 這條記錄( 注意觀察 SQL )<br>
? ? */
? ? List<ISqlParser> sqlParserList = new ArrayList<>();
? ? /**
? ? ? *此處調(diào)用重寫的類
? ? ? *
? ? ? */
? ? 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);
? ? ? ? ? ? // 過濾自定義查詢此時(shí)無租戶信息約束【 麻花藤 】出現(xiàn)
? ? ? ? ? ? if ("com.baomidou.springboot.mapper.UserMapper.selectListBySQL".equals(ms.getId())) {
? ? ? ? ? ? ? ? return true;
? ? ? ? ? ? }
? ? ? ? ? ? return false;
? ? ? ? }
? ? });
? ? return paginationInterceptor;
}