Feat/20241129210747 (#6631)

* 支持@InterceptorIgnore作用在default方法上.

https://github.com/baomidou/mybatis-plus/issues/6613

* 新增插件跳过执行方法.
This commit is contained in:
nieqiurong 2024-12-11 16:05:46 +08:00 committed by GitHub
parent feb80ffe94
commit 5d280b4b43
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 99 additions and 2 deletions

View File

@ -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));

View File

@ -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<T> 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();
}
}
}
}

View File

@ -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> T
* @return 返回值
* @since 3.5.10
*/
public static <T> T execute(IgnoreStrategy ignoreStrategy, Supplier<T> supplier) {
try {
handle(ignoreStrategy);
return supplier.get();
} finally {
clearIgnoreStrategy();
}
}
/**
* 初始化缓存
* <p>

View File

@ -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<Entity> {
/*
* 请注意: 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);
}

View File

@ -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<EntityMapper> {
Page<Entity> 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