干燥机配套车间生产管理系统/云平台服务端
bsw215583320
2024-04-16 c2fccb01b972176dc3da5a497b5e904025e9e98d
jeecg-boot-base-core/src/main/java/org/jeecg/config/mybatis/MybatisPlusSaasConfig.java
¶Ô±ÈÐÂÎļþ
@@ -0,0 +1,167 @@
package org.jeecg.config.mybatis;
import java.util.ArrayList;
import java.util.List;
import cn.hutool.core.util.ObjectUtil;
import com.baomidou.mybatisplus.extension.plugins.inner.DynamicTableNameInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
import org.jeecg.common.config.TenantContext;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.constant.TenantConstant;
import org.jeecg.common.util.SpringContextUtils;
import org.jeecg.common.util.TokenUtils;
import org.jeecg.common.util.oConvertUtils;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
import net.sf.jsqlparser.expression.Expression;
import net.sf.jsqlparser.expression.LongValue;
/**
 * å•数据源配置(jeecg.datasource.open = false时生效)
 * @Author zhoujf
 *
 */
@Configuration
@MapperScan(value={"org.jeecg.modules.**.mapper*"})
public class MybatisPlusSaasConfig {
    /**
     * æ˜¯å¦å¼€å¯ç³»ç»Ÿæ¨¡å—的租户隔离
     *  æŽ§åˆ¶èŒƒå›´ï¼šç”¨æˆ·ã€è§’色、部门、我的部门、字典、分类字典、多数据源、职务、通知公告
     *
     *  å®žçŽ°åŠŸèƒ½
     *  1.用户表通过硬编码实现租户ID隔离
     *  2.角色、部门、我的部门、字典、分类字典、多数据源、职务、通知公告除了硬编码还加入的 TENANT_TABLE é…ç½®ä¸­ï¼Œå®žçŽ°ç§Ÿæˆ·éš”ç¦»æ›´å®‰å…¨
     *  3.菜单表、租户表不做租户隔离
     *  4.通过拦截器MybatisInterceptor实现,增删改查数据 è‡ªåŠ¨æ³¨å…¥ç§Ÿæˆ·ID
     */
    public static final Boolean OPEN_SYSTEM_TENANT_CONTROL = true;
    /**
     * å“ªäº›è¡¨éœ€è¦åšå¤šç§Ÿæˆ· è¡¨éœ€è¦æ·»åŠ ä¸€ä¸ªå­—æ®µ tenant_id
     */
    public static final List<String> TENANT_TABLE = new ArrayList<String>();
    static {
        //1.需要租户隔离的表请在此配置
        if (MybatisPlusSaasConfig.OPEN_SYSTEM_TENANT_CONTROL) {
            //a.系统管理表
            TENANT_TABLE.add("sys_role");
            TENANT_TABLE.add("sys_user_role");
            TENANT_TABLE.add("sys_depart");
            TENANT_TABLE.add("sys_category");
            TENANT_TABLE.add("sys_data_source");
            TENANT_TABLE.add("sys_position");
            TENANT_TABLE.add("sys_announcement");
        }
        //2.示例测试
        //TENANT_TABLE.add("demo");
        //3.online租户隔离测试
        //TENANT_TABLE.add("ceapp_issue");
        TENANT_TABLE.add("dry_eqp_type");
        TENANT_TABLE.add("dry_equipment");
        TENANT_TABLE.add("dry_eqp_type");
        TENANT_TABLE.add("dry_herb");
        TENANT_TABLE.add("dry_herb_type");
        TENANT_TABLE.add("dry_order");
        TENANT_TABLE.add("dry_shop");
    }
    @Bean
    public MybatisPlusInterceptor mybatisPlusInterceptor() {
        MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
        // å…ˆ add TenantLineInnerInterceptor å† add PaginationInnerInterceptor
        interceptor.addInnerInterceptor(new TenantLineInnerInterceptor(new TenantLineHandler() {
            @Override
            public Expression getTenantId() {
                String tenantId = TenantContext.getTenant();
                //如果通过线程获取租户ID为空,则通过当前请求的request获取租户(shiro排除拦截器的请求会获取不到租户ID)
                if(oConvertUtils.isEmpty(tenantId)){
                    try {
                        tenantId = TokenUtils.getTenantIdByRequest(SpringContextUtils.getHttpServletRequest());
                    } catch (Exception e) {
                        //e.printStackTrace();
                    }
                }
                if(oConvertUtils.isEmpty(tenantId)){
                    tenantId = "0";
                }
                return new LongValue(tenantId);
            }
            @Override
            public String getTenantIdColumn(){
                return TenantConstant.TENANT_ID_TABLE;
            }
            // è¿”回 true è¡¨ç¤ºä¸èµ°ç§Ÿæˆ·é€»è¾‘
            @Override
            public boolean ignoreTable(String tableName) {
                for(String temp: TENANT_TABLE){
                    if(temp.equalsIgnoreCase(tableName)){
                        return false;
                    }
                }
                return true;
            }
        }));
        //update-begin-author:zyf date:20220425 for:【VUEN-606】注入动态表名适配拦截器解决多表名问题
        interceptor.addInnerInterceptor(dynamicTableNameInnerInterceptor());
        //update-end-author:zyf date:20220425 for:【VUEN-606】注入动态表名适配拦截器解决多表名问题
        interceptor.addInnerInterceptor(new PaginationInnerInterceptor());
        //【jeecg-boot/issues/3847】增加@Version乐观锁支持
        interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
        return interceptor;
    }
    /**
     * åŠ¨æ€è¡¨ååˆ‡æ¢æ‹¦æˆªå™¨,用于适配vue2和vue3同一个表有多个的情况,如sys_role_index在vue3情况下表名为sys_role_index_v3
     * @return
     */
    private DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor() {
        DynamicTableNameInnerInterceptor dynamicTableNameInnerInterceptor = new DynamicTableNameInnerInterceptor();
        dynamicTableNameInnerInterceptor.setTableNameHandler((sql, tableName) -> {
            //获取需要动态解析的表名
            String dynamicTableName = ThreadLocalDataHelper.get(CommonConstant.DYNAMIC_TABLE_NAME);
            //当dynamicTableName不为空时才走动态表名处理逻辑,否则返回原始表名
            if (ObjectUtil.isNotEmpty(dynamicTableName) && dynamicTableName.equals(tableName)) {
                // èŽ·å–å‰ç«¯ä¼ é€’çš„ç‰ˆæœ¬å·æ ‡è¯†
                Object version = ThreadLocalDataHelper.get(CommonConstant.VERSION);
                if (ObjectUtil.isNotEmpty(version)) {
                    //拼接表名规则(原始表名+下划线+前端传递的版本号)
                    return tableName + "_" + version;
                }
            }
            return tableName;
        });
        return dynamicTableNameInnerInterceptor;
    }
//    /**
//     * ä¸‹ä¸ªç‰ˆæœ¬ä¼šåˆ é™¤ï¼ŒçŽ°åœ¨ä¸ºäº†é¿å…ç¼“å­˜å‡ºçŽ°é—®é¢˜ä¸å¾—ä¸é…ç½®
//     * @return
//     */
//    @Bean
//    public ConfigurationCustomizer configurationCustomizer() {
//        return configuration -> configuration.setUseDeprecatedExecutor(false);
//    }
//    /**
//     * mybatis-plus SQL执行效率插件【生产环境可以关闭】
//     */
//    @Bean
//    public PerformanceInterceptor performanceInterceptor() {
//        return new PerformanceInterceptor();
//    }
}