In microservice projects, tenant isolation is enabled by default, but in some cases, individual methods need not be enabled.
To achieve this goal, a custom annotation that ignores tenant isolation is defined:
@IgnoreTenant
Just add it to the method, for example:
@IgnoreTenant public CrmSmsTemplate getTemplateByCodeAndTenandtId(String code, Integer tenantId) { return (new QueryWrapper<CrmSmsTemplate>().eq("code", code).eq("tenant_id", tenantId)); }
Implementation steps:
1. First define the configuration class of MybatisPlus to create an interceptor MybatisPlusInterceptor
Modify the mybatisPlusInterceptor method in MybatisPlusSaasConfig
@Bean public MybatisPlusInterceptor mybatisPlusInterceptor() { MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor(); // First add TenantLineInnerInterceptor and then add PaginationInnerInterceptor (new TenantLineInnerInterceptor(new TenantLineHandler() { @Override public Expression getTenantId() { String tenantId = (); //If the tenant ID is obtained through thread is empty, the tenant will be obtained through the request of the current request (shiro's request to exclude the interceptor will not be able to obtain the tenant ID) if((tenantId)){ try { tenantId = (()); } catch (Exception e) { //(); } } if((tenantId)){ tenantId = "0"; } return new LongValue(tenantId); } @Override public String getTenantIdColumn(){ return TenantConstant.TENANT_ID_TABLE; } // Return true means that the tenant logic is not removed @Override public boolean ignoreTable(String tableName) { for(String temp: TENANT_TABLE){ if((tableName)){ if ((())){ return (); } return false; } } return true; } /*@Override public boolean ignoreTable(String tableName) { if ((())){ return (); } return true; }*/ })); //update-begin-author:zyf date:20220425 for:【VUEN-606】Inject dynamic table name adapter to solve the problem of multiple table names (dynamicTableNameInnerInterceptor()); //update-end-author:zyf date:20220425 for:【VUEN-606】Inject dynamic table name adapter to solve the problem of multiple table names (new PaginationInnerInterceptor()); //【jeecg-boot/issues/3847】Add @Version optimistic lock support (new OptimisticLockerInnerInterceptor()); return interceptor; }
2. Define a ThreadLocal local thread variable MybatisTenantContext is used to maintain whether to enable tenant isolation variables
package ; public class MybatisTenantContext { private static final ThreadLocal<Boolean> TENANT_CONTEXT_THREAD_LOCAL = new ThreadLocal<>(); public static Boolean get() { return TENANT_CONTEXT_THREAD_LOCAL.get(); } public static void set(boolean isIgnore){ TENANT_CONTEXT_THREAD_LOCAL.set(isIgnore); } public static void clear(){ TENANT_CONTEXT_THREAD_LOCAL.remove(); } }
3. Custom annotations
package ; import ; import ; import ; import ; @Retention() @Target({, }) public @interface IgnoreTenant { /** * true for not doing tenant isolation false for tenant isolation * @return */ boolean isIgnore() default true; }
4. Annotation facets
ps: If there are other annotations on the method or class that are used for tenant isolation, such as: log annotations, dictionariestranslateThe annotation executes logic after (). Pay attention to the execution order of the aspect class, and be sure to ensure that TenantIgnoreAspect is executed first, otherwise other annotations will still be isolated from tenants. You can add @Order(Integer.MIN_VALUE) annotation to the TenantIgnoreAspect aspect class to ensure execution order
package ; import .slf4j.Slf4j; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import ; import .*; import ; import ; import ; import ; @Aspect @Slf4j @Component @Order(Integer.MIN_VALUE) public class TenantIgnoreAspect { /** * Point of entry */ @Pointcut("@within() ||@annotation()") public void pointcut() { } @Around("pointcut()") public Object around(ProceedingJoinPoint point) throws Throwable { try { Class<?> targetClass = ().getClass(); IgnoreTenant classIgnoreTenant = (); MethodSignature signature = (MethodSignature) (); Method method = (); IgnoreTenant methodIgnoreTenant = (); //Judge whether there are any annotations on the class boolean isClassAnnotated = (, targetClass); //Does there be any annotations in the method of judging whether there are any comments boolean isMethodAnnotated = (methodIgnoreTenant); //If there is a class if (isClassAnnotated) { (()); } //If there is a method, it is mainly based on the method. if (isMethodAnnotated) { (()); } Object result = (); return result; } finally { (); } } }
So far you can use the annotation: @IgnoreTenant
Added: If there are multiple queries in a method, but only specific queries need to ignore tenant isolation, you can use the following method
@Service public class DemoService { public List<String> demoList(String name){ try { (true); (name); return (); }finally { (); } } }
The above code is to manually maintain the local thread variable MybatisTenantContext. Annotations cannot be used. You must remember to clear after using it. For more related content related to MyBatis-Plus ignore multi-tenant isolation, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!