From 5d280b4b43267fdb963aff8c0683e30bbdd6aca8 Mon Sep 17 00:00:00 2001 From: nieqiurong Date: Wed, 11 Dec 2024 16:05:46 +0800 Subject: [PATCH] Feat/20241129210747 (#6631) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 支持@InterceptorIgnore作用在default方法上. https://github.com/baomidou/mybatis-plus/issues/6613 * 新增插件跳过执行方法. --- .../core/MybatisMapperAnnotationBuilder.java | 2 +- .../core/override/MybatisMapperProxy.java | 17 +++++++++- .../core/plugins/InterceptorIgnoreHelper.java | 30 ++++++++++++++++++ .../mybatisplus/test/tenant/EntityMapper.java | 31 +++++++++++++++++++ .../mybatisplus/test/tenant/TenantTest.java | 21 +++++++++++++ 5 files changed, 99 insertions(+), 2 deletions(-) diff --git a/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisMapperAnnotationBuilder.java b/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisMapperAnnotationBuilder.java index 6b2f5fb3c..9e7e723d3 100644 --- a/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisMapperAnnotationBuilder.java +++ b/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/MybatisMapperAnnotationBuilder.java @@ -96,6 +96,7 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder { parseCacheRef(); IgnoreStrategy ignoreStrategy = InterceptorIgnoreHelper.initSqlParserInfoCache(type); for (Method method : type.getMethods()) { + InterceptorIgnoreHelper.initSqlParserInfoCache(ignoreStrategy, mapperName, method); if (!canHaveStatement(method)) { continue; } @@ -104,7 +105,6 @@ public class MybatisMapperAnnotationBuilder extends MapperAnnotationBuilder { parseResultMap(method); } try { - InterceptorIgnoreHelper.initSqlParserInfoCache(ignoreStrategy, mapperName, method); parseStatement(method); } catch (IncompleteElementException e) { configuration.addIncompleteMethod(new MybatisMethodResolver(this, method)); diff --git a/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/override/MybatisMapperProxy.java b/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/override/MybatisMapperProxy.java index ca1d3ab6e..53013735a 100644 --- a/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/override/MybatisMapperProxy.java +++ b/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/override/MybatisMapperProxy.java @@ -15,6 +15,9 @@ */ package com.baomidou.mybatisplus.core.override; +import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy; +import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; +import com.baomidou.mybatisplus.core.toolkit.StringPool; import org.apache.ibatis.binding.MapperProxy; import org.apache.ibatis.reflection.ExceptionUtil; import org.apache.ibatis.session.SqlSession; @@ -163,7 +166,19 @@ public class MybatisMapperProxy implements InvocationHandler, Serializable { @Override public Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable { - return methodHandle.bindTo(proxy).invokeWithArguments(args); + try { + String className = method.getDeclaringClass().getName(); + IgnoreStrategy ignoreStrategy = InterceptorIgnoreHelper.getIgnoreStrategy(className + StringPool.DOT + method.getName()); + if (ignoreStrategy == null) { + ignoreStrategy = InterceptorIgnoreHelper.getIgnoreStrategy(className); + } + if (ignoreStrategy != null) { + InterceptorIgnoreHelper.handle(ignoreStrategy); + } + return methodHandle.bindTo(proxy).invokeWithArguments(args); + } finally { + InterceptorIgnoreHelper.clearIgnoreStrategy(); + } } } } diff --git a/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/plugins/InterceptorIgnoreHelper.java b/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/plugins/InterceptorIgnoreHelper.java index 6472dbbe1..013ec5e08 100644 --- a/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/plugins/InterceptorIgnoreHelper.java +++ b/mybatis-plus-core/src/main/java/com/baomidou/mybatisplus/core/plugins/InterceptorIgnoreHelper.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.function.Function; +import java.util.function.Supplier; /** * @author miemie @@ -82,6 +83,35 @@ public abstract class InterceptorIgnoreHelper { return null; } + /** + * 获取忽略策略缓存信息 + * + * @param key key + * @return 策略信息 + * @since 3.5.10 + */ + public static IgnoreStrategy getIgnoreStrategy(String key) { + return IGNORE_STRATEGY_CACHE.get(key); + } + + /** + * 按指定策略执行指定方法 + * + * @param ignoreStrategy 忽略策略 + * @param supplier 执行方法 + * @param T + * @return 返回值 + * @since 3.5.10 + */ + public static T execute(IgnoreStrategy ignoreStrategy, Supplier supplier) { + try { + handle(ignoreStrategy); + return supplier.get(); + } finally { + clearIgnoreStrategy(); + } + } + /** * 初始化缓存 *

diff --git a/mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/tenant/EntityMapper.java b/mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/tenant/EntityMapper.java index ab32e706b..4b6b05a0c 100644 --- a/mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/tenant/EntityMapper.java +++ b/mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/tenant/EntityMapper.java @@ -1,12 +1,43 @@ package com.baomidou.mybatisplus.test.tenant; +import com.baomidou.mybatisplus.annotation.InterceptorIgnore; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import org.apache.ibatis.annotations.CacheNamespace; +import java.io.Serializable; + /** * @author miemie * @since 2020-06-24 */ @CacheNamespace public interface EntityMapper extends BaseMapper { + + /* + * 请注意: Mybatis的接口方法虽然支持重载,但是底层MappedStatement是只能有一份的,也就是MappedStatement(类名+方法名)组成唯一性. + * + * 低版本(<3.5.10)下,忽略BaseMapper上的方法,可通过重写其中方法来标记 + * 例如忽略deleteById方法,直接覆写 int deleteById(Entity entity); 这样就会把deleteById相关的重载方法都会重写掉,因为忽略方式是对MappedStatement级别生效的 + * + * (高版本才支持) + * 但是建议按照如果有需要跳过一些插件的方法,通过自定义方法标记作用跳过会好点. + * 例如我调用deleteById,默认情况下是需要拼接租户条件的,但如果有些特殊需求,想忽略跳过租户的时候,可以直接自定义个默认方法(例如deleteByIdWithIgnore)来调用baseMapper方法得deleteById + */ + + @InterceptorIgnore(tenantLine = "true") + default int deleteByIdWithIgnore(Serializable id) { + return deleteById(id); + } + + @InterceptorIgnore(tenantLine = "true") + default Entity selectByIdWithIgnore(Serializable id) { + return selectById(id); + } + +// /** +// * //TODO 由于是对ms级别的忽略,所以不考虑重载方法, 忽略deleteById方法 +// */ +// @InterceptorIgnore(tenantLine = "true") +// int deleteById(Entity entity); + } diff --git a/mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/tenant/TenantTest.java b/mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/tenant/TenantTest.java index a3bbf1db0..ee25c339e 100644 --- a/mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/tenant/TenantTest.java +++ b/mybatis-plus/src/test/java/com/baomidou/mybatisplus/test/tenant/TenantTest.java @@ -1,6 +1,8 @@ package com.baomidou.mybatisplus.test.tenant; import com.baomidou.mybatisplus.annotation.DbType; +import com.baomidou.mybatisplus.core.plugins.IgnoreStrategy; +import com.baomidou.mybatisplus.core.plugins.InterceptorIgnoreHelper; import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor; import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor; @@ -9,6 +11,7 @@ import com.baomidou.mybatisplus.test.BaseDbTest; import net.sf.jsqlparser.expression.LongValue; import org.apache.ibatis.cache.Cache; import org.apache.ibatis.plugin.Interceptor; +import org.junit.jupiter.api.Assertions; import org.junit.jupiter.api.Test; import java.util.Arrays; @@ -82,6 +85,24 @@ public class TenantTest extends BaseDbTest { Page page = m.selectPage(new Page<>(), null); assertThat(page.getTotal()).as("count 正常").isEqualTo(0); }); + + doTest(m -> { + Entity entity = new Entity().setName("秋秋").setTenantId(2); + m.insert(entity); + Assertions.assertNull(m.selectById(entity.getId())); + Assertions.assertNotNull(m.selectByIdWithIgnore(entity.getId())); + Assertions.assertEquals(0, m.deleteById(entity.getId())); + Assertions.assertEquals(1, m.deleteByIdWithIgnore(entity.getId())); + }); + + doTest(m -> { + Entity entity = new Entity().setName("秋秋").setTenantId(2); + m.insert(entity); + Assertions.assertNull(m.selectById(entity.getId())); + Assertions.assertNotNull(InterceptorIgnoreHelper.execute(IgnoreStrategy.builder().tenantLine(true).build(), () -> m.selectById(entity.getId()))); + Assertions.assertEquals(0, m.deleteById(entity.getId())); + Assertions.assertEquals(1, InterceptorIgnoreHelper.execute(IgnoreStrategy.builder().tenantLine(true).build(), () -> m.deleteById(entity.getId()))); + }); } @Override