Browse Source

tenant test

miemie 5 years ago
parent
commit
c00c8514fc

+ 25 - 43
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/TenantInnerInterceptor.java → mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/inner/TenantLineInnerInterceptor.java

@@ -5,14 +5,11 @@ import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
 import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
 import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.baomidou.mybatisplus.extension.parser.JsqlParserSupport;
-import com.baomidou.mybatisplus.extension.plugins.tenant.TenantHandler;
-import lombok.Data;
+import com.baomidou.mybatisplus.extension.plugins.tenant.TenantLineHandler;
 import lombok.RequiredArgsConstructor;
-import lombok.experimental.Accessors;
 import net.sf.jsqlparser.expression.BinaryExpression;
 import net.sf.jsqlparser.expression.Expression;
 import net.sf.jsqlparser.expression.Parenthesis;
-import net.sf.jsqlparser.expression.ValueListExpression;
 import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
 import net.sf.jsqlparser.expression.operators.conditional.OrExpression;
 import net.sf.jsqlparser.expression.operators.relational.*;
@@ -38,13 +35,11 @@ import java.util.List;
  * @author miemie
  * @since 2020-06-20
  */
-@Data
-@Accessors(chain = true)
 @RequiredArgsConstructor
 @SuppressWarnings({"rawtypes"})
-public class TenantInnerInterceptor extends JsqlParserSupport implements InnerInterceptor {
+public class TenantLineInnerInterceptor extends JsqlParserSupport implements InnerInterceptor {
 
-    private final TenantHandler tenantHandler;
+    private final TenantLineHandler tenantLineHandler;
 
     @Override
     public void beforeQuery(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
@@ -92,20 +87,25 @@ public class TenantInnerInterceptor extends JsqlParserSupport implements InnerIn
 
     @Override
     protected void processInsert(Insert insert, int index, Object obj) {
-        if (tenantHandler.doTableFilter(insert.getTable().getName())) {
+        if (tenantLineHandler.doTableFilter(insert.getTable().getName())) {
             // 过滤退出执行
             return;
         }
-        insert.getColumns().add(new Column(tenantHandler.getTenantIdColumn()));
+        List<Column> columns = insert.getColumns();
+        String tenantIdColumn = tenantLineHandler.getTenantIdColumn();
+        if (columns.stream().map(Column::getColumnName).anyMatch(i -> i.equals(tenantIdColumn))) {
+            return;
+        }
+        columns.add(new Column(tenantLineHandler.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)));
+                ((MultiExpressionList) itemsList).getExprList().forEach(el -> el.getExpressions().add(tenantLineHandler.getTenantId()));
             } else {
-                ((ExpressionList) insert.getItemsList()).getExpressions().add(tenantHandler.getTenantId(false));
+                ((ExpressionList) insert.getItemsList()).getExpressions().add(tenantLineHandler.getTenantId());
             }
         } else {
             throw ExceptionUtils.mpe("Failed to process multiple-table update, please exclude the tableName or statementId");
@@ -118,7 +118,7 @@ public class TenantInnerInterceptor extends JsqlParserSupport implements InnerIn
     @Override
     protected void processUpdate(Update update, int index, Object obj) {
         final Table table = update.getTable();
-        if (tenantHandler.doTableFilter(table.getName())) {
+        if (tenantLineHandler.doTableFilter(table.getName())) {
             // 过滤退出执行
             return;
         }
@@ -130,7 +130,7 @@ public class TenantInnerInterceptor extends JsqlParserSupport implements InnerIn
      */
     @Override
     protected void processDelete(Delete delete, int index, Object obj) {
-        if (tenantHandler.doTableFilter(delete.getTable().getName())) {
+        if (tenantLineHandler.doTableFilter(delete.getTable().getName())) {
             // 过滤退出执行
             return;
         }
@@ -144,7 +144,7 @@ public class TenantInnerInterceptor extends JsqlParserSupport implements InnerIn
         //获得where条件表达式
         EqualsTo equalsTo = new EqualsTo();
         equalsTo.setLeftExpression(this.getAliasColumn(table));
-        equalsTo.setRightExpression(tenantHandler.getTenantId(false));
+        equalsTo.setRightExpression(tenantLineHandler.getTenantId());
         if (null != where) {
             if (where instanceof OrExpression) {
                 return new AndExpression(equalsTo, new Parenthesis(where));
@@ -172,11 +172,11 @@ public class TenantInnerInterceptor extends JsqlParserSupport implements InnerIn
         FromItem fromItem = plainSelect.getFromItem();
         if (fromItem instanceof Table) {
             Table fromTable = (Table) fromItem;
-            if (!tenantHandler.doTableFilter(fromTable.getName())) {
+            if (!tenantLineHandler.doTableFilter(fromTable.getName())) {
                 //#1186 github
                 plainSelect.setWhere(builderExpression(plainSelect.getWhere(), fromTable));
                 if (addColumn) {
-                    plainSelect.getSelectItems().add(new SelectExpressionItem(new Column(tenantHandler.getTenantIdColumn())));
+                    plainSelect.getSelectItems().add(new SelectExpressionItem(new Column(tenantLineHandler.getTenantIdColumn())));
                 }
             }
         } else {
@@ -227,7 +227,7 @@ public class TenantInnerInterceptor extends JsqlParserSupport implements InnerIn
     protected void processJoin(Join join) {
         if (join.getRightItem() instanceof Table) {
             Table fromTable = (Table) join.getRightItem();
-            if (this.tenantHandler.doTableFilter(fromTable.getName())) {
+            if (this.tenantLineHandler.doTableFilter(fromTable.getName())) {
                 // 过滤退出执行
                 return;
             }
@@ -236,12 +236,10 @@ public class TenantInnerInterceptor extends JsqlParserSupport implements InnerIn
     }
 
     /**
-     * 处理条件:
-     * 支持 getTenantHandler().getTenantId()是一个完整的表达式:tenant in (1,2)
-     * 默认tenantId的表达式: LongValue(1)这种依旧支持
+     * 处理条件
      */
     protected Expression builderExpression(Expression currentExpression, Table table) {
-        final Expression tenantExpression = tenantHandler.getTenantId(true);
+        final Expression tenantExpression = tenantLineHandler.getTenantId();
         Expression appendExpression = this.processTableAlias4CustomizedTenantIdExpression(tenantExpression, table);
         if (currentExpression == null) {
             return appendExpression;
@@ -277,29 +275,13 @@ public class TenantInnerInterceptor extends JsqlParserSupport implements InnerIn
     }
 
     /**
-     * 目前: 针对自定义的tenantId的条件表达式[tenant_id in (1,2,3)],无法处理多租户的字段加上表别名
-     * select a.id, b.name
-     * from a
-     * join b on b.aid = a.id and [b.]tenant_id in (1,2) --别名[b.]无法加上 TODO
      *
-     * @param expression
-     * @param table
-     * @return 加上别名的多租户字段表达式
      */
     protected Expression processTableAlias4CustomizedTenantIdExpression(Expression expression, Table table) {
-        Expression target;
-        if (expression instanceof ValueListExpression) {
-            InExpression inExpression = new InExpression();
-            inExpression.setLeftExpression(this.getAliasColumn(table));
-            inExpression.setRightItemsList(((ValueListExpression) expression).getExpressionList());
-            target = inExpression;
-        } else {
-            EqualsTo equalsTo = new EqualsTo();
-            equalsTo.setLeftExpression(this.getAliasColumn(table));
-            equalsTo.setRightExpression(expression);
-            target = equalsTo;
-        }
-        return target;
+        EqualsTo equalsTo = new EqualsTo();
+        equalsTo.setLeftExpression(this.getAliasColumn(table));
+        equalsTo.setRightExpression(expression);
+        return equalsTo;
     }
 
     /**
@@ -314,7 +296,7 @@ public class TenantInnerInterceptor extends JsqlParserSupport implements InnerIn
         if (table.getAlias() != null) {
             column.append(table.getAlias().getName()).append(StringPool.DOT);
         }
-        column.append(tenantHandler.getTenantIdColumn());
+        column.append(tenantLineHandler.getTenantIdColumn());
         return new Column(column.toString());
     }
 }

+ 58 - 0
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/tenant/TenantLineHandler.java

@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2011-2020, baomidou (jobob@qq.com).
+ * <p>
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not
+ * use this file except in compliance with the License. You may obtain a copy of
+ * the License at
+ * <p>
+ * https://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package com.baomidou.mybatisplus.extension.plugins.tenant;
+
+import net.sf.jsqlparser.expression.Expression;
+
+/**
+ * 租户处理器( TenantId 行级 )
+ *
+ * @author hubin
+ * @since 2017-08-31
+ */
+public interface TenantLineHandler {
+
+    /**
+     * 获取租户 ID 值表达式,只支持单个 ID 值
+     * <p>
+     *
+     * @return 租户 ID 值表达式
+     */
+    Expression getTenantId();
+
+    /**
+     * 获取租户字段名
+     * <p>
+     * 默认字段名叫: tenant_id
+     *
+     * @return 租户字段名
+     */
+    default String getTenantIdColumn() {
+        return "tenant_id";
+    }
+
+    /**
+     * 根据表名判断是否进行过滤
+     * <p>
+     * 默认都要进行解析
+     *
+     * @param tableName 表名
+     * @return 是否进行过滤, true:表示忽略,false:需要解析多租户字段
+     */
+    default boolean doTableFilter(String tableName) {
+        return false;
+    }
+}

+ 29 - 2
mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/tenant/TenantTest.java

@@ -1,7 +1,7 @@
 package com.baomidou.mybatisplus.test.tenant;
 
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
-import com.baomidou.mybatisplus.extension.plugins.inner.TenantInnerInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
 import com.baomidou.mybatisplus.test.BaseDbTest;
 import net.sf.jsqlparser.expression.LongValue;
 import org.apache.ibatis.cache.Cache;
@@ -47,12 +47,39 @@ public class TenantTest extends BaseDbTest<EntityMapper> {
             assertThat(entity.getTenantId()).as("有租户信息").isEqualTo(1);
         });
         assertThat(cache.getSize()).as("依然只有一条缓存,命中了缓存").isEqualTo(1);
+
+
+        doTestAutoCommit(m -> {
+            int delete = m.deleteById(id);
+            assertThat(delete).as("删除成功").isEqualTo(1);
+        });
+        assertThat(cache.getSize()).as("update操作清空了缓存").isEqualTo(0);
+
+
+        doTestAutoCommit(m -> {
+            int insert = m.insert(new Entity().setId(id).setTenantId(2));
+            assertThat(insert).as("故意插入一个其他租户的信息,插入成功").isEqualTo(1);
+        });
+
+
+        doTest(m -> {
+            Entity entity = m.selectById(id);
+            assertThat(entity).as("搜索不到数据").isNull();
+        });
+        assertThat(cache.getSize()).as("缓存了个寂寞").isEqualTo(1);
+
+
+        doTest(m -> {
+            Entity entity = m.selectById(id);
+            assertThat(entity).as("搜索不到数据").isNull();
+        });
+        assertThat(cache.getSize()).as("依然缓存了个寂寞,说明命中的缓存").isEqualTo(1);
     }
 
     @Override
     protected List<Interceptor> interceptors() {
         MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
-        interceptor.addInnerInterceptor(new TenantInnerInterceptor(select -> new LongValue(1)));
+        interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(() -> new LongValue(1)));
         return Collections.singletonList(interceptor);
     }