瀏覽代碼

InterceptorIgnore#others 属性

miemie 4 年之前
父節點
當前提交
aaa222bef6

+ 15 - 3
mybatis-plus-annotation/src/main/java/com/baomidou/mybatisplus/annotation/InterceptorIgnore.java

@@ -5,8 +5,8 @@ import java.lang.annotation.*;
 /**
 /**
  * 内置插件的一些过滤规则
  * 内置插件的一些过滤规则
  * <p>
  * <p>
- * 支持注解在 mapper 上以及 mapper.method 上
- * 同时存在则 mapper.method 比 mapper 优先级高
+ * 支持注解在 Mapper 上以及 Mapper.Method 上
+ * 同时存在则 Mapper.method 比 Mapper 优先级高
  * <p>
  * <p>
  * 支持:
  * 支持:
  * true 和 false , 1 和 0 , on 和 off
  * true 和 false , 1 和 0 , on 和 off
@@ -43,7 +43,19 @@ public @interface InterceptorIgnore {
 
 
     /**
     /**
      * 数据权限 {@link com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor}
      * 数据权限 {@link com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor}
-     * <p>默认关闭,需要注解打开</p>
+     * <p>
+     * 默认关闭,需要注解打开
      */
      */
     String dataPermission() default "1";
     String dataPermission() default "1";
+
+    /**
+     * 其他的
+     * <p>
+     * 格式应该为:  "key"+"@"+可选项[false,true,1,0,on,off]
+     * 例如: "xxx@1" 或 "xxx@true" 或 "xxx@on"
+     * <p>
+     * 如果配置了该属性的注解是注解在 Mapper 上的,则如果该 Mapper 的一部分 Method 需要取反则需要在 Method 上注解并配置此属性为反值
+     * 例如: "xxx@1" 在 Mapper 上, 则 Method 上需要 "xxx@0"
+     */
+    String[] others() default {};
 }
 }

+ 82 - 25
mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/plugins/InterceptorIgnoreHelper.java

@@ -1,14 +1,14 @@
 package com.baomidou.mybatisplus.core.plugins;
 package com.baomidou.mybatisplus.core.plugins;
 
 
 import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
 import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
-import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
-import com.baomidou.mybatisplus.core.toolkit.StringPool;
-import com.baomidou.mybatisplus.core.toolkit.StringUtils;
+import com.baomidou.mybatisplus.core.toolkit.*;
 import lombok.Builder;
 import lombok.Builder;
 import lombok.Data;
 import lombok.Data;
 
 
 import java.lang.reflect.Method;
 import java.lang.reflect.Method;
+import java.util.HashSet;
 import java.util.Map;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.concurrent.ConcurrentHashMap;
 import java.util.function.Function;
 import java.util.function.Function;
 
 
@@ -16,7 +16,7 @@ import java.util.function.Function;
  * @author miemie
  * @author miemie
  * @since 2020-07-31
  * @since 2020-07-31
  */
  */
-public class InterceptorIgnoreHelper {
+public abstract class InterceptorIgnoreHelper {
 
 
     /**
     /**
      * SQL 解析缓存
      * SQL 解析缓存
@@ -25,63 +25,77 @@ public class InterceptorIgnoreHelper {
     private static final Map<String, InterceptorIgnoreCache> INTERCEPTOR_IGNORE_CACHE = new ConcurrentHashMap<>();
     private static final Map<String, InterceptorIgnoreCache> INTERCEPTOR_IGNORE_CACHE = new ConcurrentHashMap<>();
 
 
     /**
     /**
-     * 初始化缓存 接口上 InterceptorIgnore 注解信息
+     * 初始化缓存
+     * <p>
+     * Mapper 上 InterceptorIgnore 注解信息
      *
      *
      * @param mapperClass Mapper Class
      * @param mapperClass Mapper Class
      */
      */
     public synchronized static InterceptorIgnoreCache initSqlParserInfoCache(Class<?> mapperClass) {
     public synchronized static InterceptorIgnoreCache initSqlParserInfoCache(Class<?> mapperClass) {
         InterceptorIgnore ignore = mapperClass.getAnnotation(InterceptorIgnore.class);
         InterceptorIgnore ignore = mapperClass.getAnnotation(InterceptorIgnore.class);
         if (ignore != null) {
         if (ignore != null) {
-            return buildInterceptorIgnoreCache(ignore);
+            String key = mapperClass.getName();
+            InterceptorIgnoreCache cache = buildInterceptorIgnoreCache(key, ignore);
+            INTERCEPTOR_IGNORE_CACHE.put(key, cache);
+            return cache;
         }
         }
         return null;
         return null;
     }
     }
 
 
     /**
     /**
-     * 初始化缓存 方法上 InterceptorIgnore 注解信息
+     * 初始化缓存
+     * <p>
+     * Mapper#method 上 InterceptorIgnore 注解信息
      *
      *
      * @param mapperAnnotation Mapper Class Name
      * @param mapperAnnotation Mapper Class Name
      * @param method           Method
      * @param method           Method
      */
      */
     public static void initSqlParserInfoCache(InterceptorIgnoreCache mapperAnnotation, String mapperClassName, Method method) {
     public static void initSqlParserInfoCache(InterceptorIgnoreCache mapperAnnotation, String mapperClassName, Method method) {
         InterceptorIgnore ignore = method.getAnnotation(InterceptorIgnore.class);
         InterceptorIgnore ignore = method.getAnnotation(InterceptorIgnore.class);
-        final String key = mapperClassName.concat(StringPool.DOT).concat(method.getName());
+        String key = mapperClassName.concat(StringPool.DOT).concat(method.getName());
+        String name = mapperClassName.concat(StringPool.HASH).concat(method.getName());
         if (ignore != null) {
         if (ignore != null) {
-            InterceptorIgnoreCache methodCache = buildInterceptorIgnoreCache(ignore);
+            InterceptorIgnoreCache methodCache = buildInterceptorIgnoreCache(name, ignore);
             if (mapperAnnotation == null) {
             if (mapperAnnotation == null) {
                 INTERCEPTOR_IGNORE_CACHE.put(key, methodCache);
                 INTERCEPTOR_IGNORE_CACHE.put(key, methodCache);
                 return;
                 return;
             }
             }
             INTERCEPTOR_IGNORE_CACHE.put(key, chooseCache(mapperAnnotation, methodCache));
             INTERCEPTOR_IGNORE_CACHE.put(key, chooseCache(mapperAnnotation, methodCache));
-        } else if (mapperAnnotation != null) {
-            INTERCEPTOR_IGNORE_CACHE.put(key, mapperAnnotation);
         }
         }
     }
     }
 
 
     public static boolean willIgnoreTenantLine(String id) {
     public static boolean willIgnoreTenantLine(String id) {
-        return willIgnore(id, i -> i.getTenantLine() != null && i.getTenantLine());
+        return willIgnore(id, InterceptorIgnoreCache::getTenantLine);
     }
     }
 
 
     public static boolean willIgnoreDynamicTableName(String id) {
     public static boolean willIgnoreDynamicTableName(String id) {
-        return willIgnore(id, i -> i.getDynamicTableName() != null && i.getDynamicTableName());
+        return willIgnore(id, InterceptorIgnoreCache::getDynamicTableName);
     }
     }
 
 
     public static boolean willIgnoreBlockAttack(String id) {
     public static boolean willIgnoreBlockAttack(String id) {
-        return willIgnore(id, i -> i.getBlockAttack() != null && i.getBlockAttack());
+        return willIgnore(id, InterceptorIgnoreCache::getBlockAttack);
     }
     }
 
 
     public static boolean willIgnoreIllegalSql(String id) {
     public static boolean willIgnoreIllegalSql(String id) {
-        return willIgnore(id, i -> i.getIllegalSql() != null && i.getIllegalSql());
+        return willIgnore(id, InterceptorIgnoreCache::getIllegalSql);
     }
     }
 
 
     public static boolean willIgnoreDataPermission(String id) {
     public static boolean willIgnoreDataPermission(String id) {
-        return willIgnore(id, i -> i.getDataPermission() != null && i.getDataPermission());
+        return willIgnore(id, InterceptorIgnoreCache::getDataPermission);
+    }
+
+    public static boolean willIgnoreOthersByKey(String id, String key) {
+        return willIgnore(id, i -> CollectionUtils.isNotEmpty(i.getOthers()) && i.getOthers().getOrDefault(key, false));
     }
     }
 
 
     public static boolean willIgnore(String id, Function<InterceptorIgnoreCache, Boolean> function) {
     public static boolean willIgnore(String id, Function<InterceptorIgnoreCache, Boolean> function) {
         InterceptorIgnoreCache cache = INTERCEPTOR_IGNORE_CACHE.get(id);
         InterceptorIgnoreCache cache = INTERCEPTOR_IGNORE_CACHE.get(id);
+        if (cache == null) {
+            cache = INTERCEPTOR_IGNORE_CACHE.get(id.substring(0, id.lastIndexOf(StringPool.DOT)));
+        }
         if (cache != null) {
         if (cache != null) {
-            return function.apply(cache);
+            Boolean apply = function.apply(cache);
+            return apply != null && apply;
         }
         }
         return false;
         return false;
     }
     }
@@ -93,20 +107,22 @@ public class InterceptorIgnoreHelper {
             .blockAttack(chooseBoolean(mapper.getBlockAttack(), method.getBlockAttack()))
             .blockAttack(chooseBoolean(mapper.getBlockAttack(), method.getBlockAttack()))
             .illegalSql(chooseBoolean(mapper.getIllegalSql(), method.getIllegalSql()))
             .illegalSql(chooseBoolean(mapper.getIllegalSql(), method.getIllegalSql()))
             .dataPermission(chooseBoolean(mapper.getDataPermission(), method.getDataPermission()))
             .dataPermission(chooseBoolean(mapper.getDataPermission(), method.getDataPermission()))
+            .others(chooseOthers(mapper.getOthers(), method.getOthers()))
             .build();
             .build();
     }
     }
 
 
-    private static InterceptorIgnoreCache buildInterceptorIgnoreCache(InterceptorIgnore ignore) {
+    private static InterceptorIgnoreCache buildInterceptorIgnoreCache(String name, InterceptorIgnore ignore) {
         return InterceptorIgnoreCache.builder()
         return InterceptorIgnoreCache.builder()
-            .tenantLine(getBoolean(ignore.tenantLine()))
-            .dynamicTableName(getBoolean(ignore.dynamicTableName()))
-            .blockAttack(getBoolean(ignore.blockAttack()))
-            .illegalSql(getBoolean(ignore.illegalSql()))
-            .dataPermission(getBoolean(ignore.dataPermission()))
+            .tenantLine(getBoolean("tenantLine", name, ignore.tenantLine()))
+            .dynamicTableName(getBoolean("dynamicTableName", name, ignore.dynamicTableName()))
+            .blockAttack(getBoolean("blockAttack", name, ignore.blockAttack()))
+            .illegalSql(getBoolean("illegalSql", name, ignore.illegalSql()))
+            .dataPermission(getBoolean("dataPermission", name, ignore.dataPermission()))
+            .others(getOthers(name, ignore.others()))
             .build();
             .build();
     }
     }
 
 
-    private static Boolean getBoolean(String value) {
+    private static Boolean getBoolean(String node, String name, String value) {
         if (StringUtils.isBlank(value)) {
         if (StringUtils.isBlank(value)) {
             return null;
             return null;
         }
         }
@@ -116,9 +132,27 @@ public class InterceptorIgnoreHelper {
         if ("0".equals(value) || "false".equals(value) || "off".equals(value)) {
         if ("0".equals(value) || "false".equals(value) || "off".equals(value)) {
             return false;
             return false;
         }
         }
-        throw ExceptionUtils.mpe("not support this value of \"%s\"", value);
+        throw ExceptionUtils.mpe("unsupported value \"%s\" by `@InterceptorIgnore#%s` on top of \"%s\"", value, node, name);
     }
     }
 
 
+    private static Map<String, Boolean> getOthers(String name, String[] values) {
+        if (ArrayUtils.isEmpty(values)) {
+            return null;
+        }
+        Map<String, Boolean> map = CollectionUtils.newHashMapWithExpectedSize(values.length);
+        for (String s : values) {
+            int index = s.indexOf(StringPool.AT);
+            Assert.isTrue(index > 0, "unsupported value \"%s\" by `@InterceptorIgnore#others` on top of \"%s\"", s, name);
+            String key = s.substring(0, index);
+            Boolean value = getBoolean("others", name, s.substring(index + 1));
+            map.put(key, value);
+        }
+        return map;
+    }
+
+    /**
+     * mapper#method 上的注解 优先级大于 mapper 上的注解
+     */
     private static Boolean chooseBoolean(Boolean mapper, Boolean method) {
     private static Boolean chooseBoolean(Boolean mapper, Boolean method) {
         if (mapper == null && method == null) {
         if (mapper == null && method == null) {
             return null;
             return null;
@@ -129,6 +163,28 @@ public class InterceptorIgnoreHelper {
         return mapper;
         return mapper;
     }
     }
 
 
+    private static Map<String, Boolean> chooseOthers(Map<String, Boolean> mapper, Map<String, Boolean> method) {
+        boolean emptyMapper = CollectionUtils.isEmpty(mapper);
+        boolean emptyMethod = CollectionUtils.isEmpty(method);
+        if (emptyMapper && emptyMethod) {
+            return null;
+        }
+        if (emptyMapper) {
+            return method;
+        }
+        if (emptyMethod) {
+            return mapper;
+        }
+        Set<String> mapperKeys = mapper.keySet();
+        Set<String> methodKeys = method.keySet();
+        Set<String> keys = new HashSet<>(mapperKeys.size() + methodKeys.size());
+        keys.addAll(methodKeys);
+        keys.addAll(mapperKeys);
+        Map<String, Boolean> map = CollectionUtils.newHashMapWithExpectedSize(keys.size());
+        methodKeys.forEach(k -> map.put(k, chooseBoolean(mapper.get(k), method.get(k))));
+        return map;
+    }
+
     @Data
     @Data
     @Builder
     @Builder
     public static class InterceptorIgnoreCache {
     public static class InterceptorIgnoreCache {
@@ -137,5 +193,6 @@ public class InterceptorIgnoreHelper {
         private Boolean blockAttack;
         private Boolean blockAttack;
         private Boolean illegalSql;
         private Boolean illegalSql;
         private Boolean dataPermission;
         private Boolean dataPermission;
+        private Map<String, Boolean> others;
     }
     }
 }
 }

+ 72 - 13
mybatis-plus-core/src/test/java/com/baomidou/mybatisplus/core/plugins/InterceptorIgnoreHelperTest.java

@@ -1,6 +1,7 @@
 package com.baomidou.mybatisplus.core.plugins;
 package com.baomidou.mybatisplus.core.plugins;
 
 
 import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
 import com.baomidou.mybatisplus.annotation.InterceptorIgnore;
+import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.api.Test;
 
 
 import java.lang.reflect.Method;
 import java.lang.reflect.Method;
@@ -13,28 +14,66 @@ import static org.assertj.core.api.Assertions.assertThat;
  */
  */
 class InterceptorIgnoreHelperTest {
 class InterceptorIgnoreHelperTest {
 
 
+    @BeforeEach
+    void beforeEach() {
+        init(Xx.class);
+        init(Pp.class);
+        init(Gg.class);
+    }
+
     @Test
     @Test
     void m1() {
     void m1() {
-        InterceptorIgnoreHelper.InterceptorIgnoreCache cache = InterceptorIgnoreHelper.initSqlParserInfoCache(Xx.class);
-        for (Method method : Xx.class.getMethods()) {
-            InterceptorIgnoreHelper.initSqlParserInfoCache(cache, Xx.class.getName(), method);
+        checkTenantLine(Xx.class, "gg", true);
+        checkTenantLine(Xx.class, "hh", false);
+        checkTenantLine(Xx.class, "mm", true);
+
+        checkTenantLine(Pp.class, "pp", false);
+        checkTenantLine(Pp.class, "dd", true);
+        checkTenantLine(Pp.class, "mj", false);
+
+        checkTenantLine(Gg.class, "uu", true);
+
+        checkOthers(Xx.class, "gg", "loli", false);
+        checkOthers(Xx.class, "gg", "mn", false);
+        checkOthers(Xx.class, "hh", "loli", true);
+        checkOthers(Xx.class, "hh", "mn", true);
+
+        checkOthers(Pp.class, "pp", "loli", true);
+        checkOthers(Pp.class, "dd", "loli", false);
+
+        // 不存在的
+        checkOthers(Pp.class, "mj", "xxxxx", false);
+    }
+
+    private void init(Class<?> clazz) {
+        InterceptorIgnoreHelper.InterceptorIgnoreCache cache = InterceptorIgnoreHelper.initSqlParserInfoCache(clazz);
+        for (Method method : clazz.getMethods()) {
+            InterceptorIgnoreHelper.initSqlParserInfoCache(cache, clazz.getName(), method);
         }
         }
-        boolean b = InterceptorIgnoreHelper.willIgnoreTenantLine(
-            "com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelperTest$Xx.gg");
-        assertThat(b).isTrue();
+    }
 
 
-        b = InterceptorIgnoreHelper.willIgnoreTenantLine(
-            "com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelperTest$Xx.hh");
-        assertThat(b).isFalse();
+    private void checkTenantLine(Class<?> clazz, String method, boolean mustTrue) {
+        boolean result = InterceptorIgnoreHelper.willIgnoreTenantLine(clazz.getName().concat(".").concat(method));
+        if (mustTrue) {
+            assertThat(result).isTrue();
+        } else {
+            assertThat(result).isFalse();
+        }
+    }
 
 
-        b = InterceptorIgnoreHelper.willIgnoreTenantLine(
-            "com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelperTest$Xx.mm");
-        assertThat(b).isTrue();
+    private void checkOthers(Class<?> clazz, String method, String key, boolean mustTrue) {
+        boolean result = InterceptorIgnoreHelper.willIgnoreOthersByKey(clazz.getName().concat(".").concat(method), key);
+        if (mustTrue) {
+            assertThat(result).isTrue();
+        } else {
+            assertThat(result).isFalse();
+        }
     }
     }
 
 
-    @InterceptorIgnore(tenantLine = "on")
+    @InterceptorIgnore(tenantLine = "on", others = {"loli@1", "mn@1"})
     interface Xx {
     interface Xx {
 
 
+        @InterceptorIgnore(others = {"loli@0", "mn@0"})
         void gg();
         void gg();
 
 
         @InterceptorIgnore(tenantLine = "off")
         @InterceptorIgnore(tenantLine = "off")
@@ -42,5 +81,25 @@ class InterceptorIgnoreHelperTest {
 
 
         @InterceptorIgnore(illegalSql = "off")
         @InterceptorIgnore(illegalSql = "off")
         void mm();
         void mm();
+
+        void ds();
+    }
+
+    interface Pp {
+
+        @InterceptorIgnore(tenantLine = "0", others = "loli@1")
+        void pp();
+
+        @InterceptorIgnore(tenantLine = "1")
+        void dd();
+
+        @InterceptorIgnore
+        void mj();
+    }
+
+    @InterceptorIgnore(tenantLine = "1")
+    interface Gg {
+
+        void uu();
     }
     }
 }
 }

+ 2 - 1
mybatis-plus-extension/src/main/java/com/baomidou/mybatisplus/extension/plugins/MybatisPlusInterceptor.java

@@ -1,6 +1,7 @@
 package com.baomidou.mybatisplus.extension.plugins;
 package com.baomidou.mybatisplus.extension.plugins;
 
 
 import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
 import com.baomidou.mybatisplus.core.toolkit.ClassUtils;
+import com.baomidou.mybatisplus.core.toolkit.StringPool;
 import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.InnerInterceptor;
 import com.baomidou.mybatisplus.extension.toolkit.PropertyMapper;
 import com.baomidou.mybatisplus.extension.toolkit.PropertyMapper;
 import lombok.Setter;
 import lombok.Setter;
@@ -113,7 +114,7 @@ public class MybatisPlusInterceptor implements Interceptor {
     @Override
     @Override
     public void setProperties(Properties properties) {
     public void setProperties(Properties properties) {
         PropertyMapper pm = PropertyMapper.newInstance(properties);
         PropertyMapper pm = PropertyMapper.newInstance(properties);
-        Map<String, Properties> group = pm.group("@");
+        Map<String, Properties> group = pm.group(StringPool.AT);
         group.forEach((k, v) -> {
         group.forEach((k, v) -> {
             InnerInterceptor innerInterceptor = ClassUtils.newInstance(k);
             InnerInterceptor innerInterceptor = ClassUtils.newInstance(k);
             innerInterceptor.setProperties(v);
             innerInterceptor.setProperties(v);