Sfoglia il codice sorgente

add 增加多租户模式
@Description
当entity类集成TenantGenericEntity时,则该类开启多租户模式,表明和类名之间请使用@TableName进行转换,
转换格式为驼峰-下划线,例SysDict-sys_dict

18339543638 3 anni fa
parent
commit
07a04902ea

+ 1 - 1
coffee-admin/src/main/java/com/coffee/admin/AdminApplication.java

@@ -12,7 +12,7 @@ import springfox.documentation.swagger2.annotations.EnableSwagger2;
  *
  *
  * @author Kevin
  * @author Kevin
  */
  */
-@SpringBootApplication(scanBasePackages = "com.coffee", exclude = {DataSourceAutoConfiguration.class})
+@SpringBootApplication(scanBasePackages ={"com.coffee"}, exclude = {DataSourceAutoConfiguration.class})
 @Import(cn.hutool.extra.spring.SpringUtil.class)
 @Import(cn.hutool.extra.spring.SpringUtil.class)
 @EnableSwagger2
 @EnableSwagger2
 public class AdminApplication {
 public class AdminApplication {

+ 3 - 1
coffee-admin/src/main/resources/application.yml

@@ -44,7 +44,7 @@ logging:
   config: classpath:logback.xml
   config: classpath:logback.xml
 
 
 mybatis-plus:
 mybatis-plus:
-  mapperPackage: com.coffee.**.mapper,com.coffee.framework.test.mapper
+  mapperPackage: com.coffee.**.mapper
   mapperLocations: classpath*:mapper/**/*Mapper.xml
   mapperLocations: classpath*:mapper/**/*Mapper.xml
   checkConfigLocation: false
   checkConfigLocation: false
   global-config:
   global-config:
@@ -52,3 +52,5 @@ mybatis-plus:
     enableSqlRunner: false
     enableSqlRunner: false
     dbConfig:
     dbConfig:
       idType: ASSIGN_ID
       idType: ASSIGN_ID
+  configuration:
+    log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

+ 18 - 0
coffee-common/src/main/java/com/coffee/common/entity/TenantGenericEntity.java

@@ -0,0 +1,18 @@
+package com.coffee.common.entity;
+
+import com.baomidou.mybatisplus.annotation.TableField;
+import lombok.Getter;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName TenetGenericEntity.java
+ * @Description 多租户父类
+ * @createTime 2022年03月15日 17:02:00
+ */
+public abstract class TenantGenericEntity<PK,TN> extends GenericEntity<PK> {
+
+    @Getter
+    @TableField("tenant_id")
+    private TN tenantId;
+}

+ 25 - 0
coffee-framework/src/main/java/com/coffee/framework/config/SaConfig.java

@@ -0,0 +1,25 @@
+package com.coffee.framework.config;
+
+import cn.dev33.satoken.SaManager;
+import cn.dev33.satoken.dao.SaTokenDaoRedisJackson;
+import lombok.AllArgsConstructor;
+import org.springframework.stereotype.Component;
+
+import javax.annotation.PostConstruct;
+
+/**
+ * @author lifang
+ * @version 1.0.0
+ * @ClassName SaConfig.java
+ * @Description TODO
+ * @createTime 2022年03月15日 16:51:00
+ */
+@Component
+@AllArgsConstructor
+public class SaConfig {
+    private final SaTokenDaoRedisJackson saTokenDaoRedisJackson;
+    @PostConstruct
+    public void init(){
+        SaManager.setSaTokenDao(saTokenDaoRedisJackson);
+    }
+}

+ 90 - 1
coffee-framework/src/main/java/com/coffee/framework/config/mybatisplus/MybatisPlusConfig.java

@@ -1,17 +1,40 @@
 package com.coffee.framework.config.mybatisplus;
 package com.coffee.framework.config.mybatisplus;
 
 
+import cn.hutool.core.collection.CollectionUtil;
+import cn.hutool.core.io.FileUtil;
+import cn.hutool.core.util.ClassUtil;
+import cn.hutool.core.util.ObjectUtil;
+import cn.hutool.core.util.StrUtil;
 import com.baomidou.mybatisplus.annotation.DbType;
 import com.baomidou.mybatisplus.annotation.DbType;
+import com.baomidou.mybatisplus.annotation.TableName;
 import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
 import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.handler.TenantLineHandler;
 import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.DataPermissionInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.OptimisticLockerInnerInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
 import com.baomidou.mybatisplus.extension.plugins.inner.PaginationInnerInterceptor;
+import com.baomidou.mybatisplus.extension.plugins.inner.TenantLineInnerInterceptor;
+import com.coffee.common.entity.TenantGenericEntity;
 import com.coffee.framework.config.mybatisplus.handler.CreateAndUpdateMetaObjectHandler;
 import com.coffee.framework.config.mybatisplus.handler.CreateAndUpdateMetaObjectHandler;
 import com.coffee.framework.config.mybatisplus.handler.CustomDataPermissionHandler;
 import com.coffee.framework.config.mybatisplus.handler.CustomDataPermissionHandler;
+import lombok.AllArgsConstructor;
+import net.sf.jsqlparser.expression.Expression;
+import net.sf.jsqlparser.expression.StringValue;
+import net.sf.jsqlparser.schema.Column;
 import org.mybatis.spring.annotation.MapperScan;
 import org.mybatis.spring.annotation.MapperScan;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.context.ApplicationContext;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.core.io.Resource;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
 import org.springframework.transaction.annotation.EnableTransactionManagement;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.annotation.PostConstruct;
+import java.io.IOException;
+import java.util.*;
+import java.util.stream.Collectors;
 
 
 /**
 /**
  * mybatis-plus配置类
  * mybatis-plus配置类
@@ -20,9 +43,39 @@ import org.springframework.transaction.annotation.EnableTransactionManagement;
  */
  */
 @EnableTransactionManagement(proxyTargetClass = true)
 @EnableTransactionManagement(proxyTargetClass = true)
 @Configuration
 @Configuration
-@MapperScan("${mybatis-plus.mapperPackage}")
+@MapperScan({"${mybatis-plus.mapperPackage}","com.coffee.framework.test.mapper"})
 public class MybatisPlusConfig {
 public class MybatisPlusConfig {
 
 
+    private final TenantIdManager tenantIdManager;
+
+    private final List<Class<?>> tableClass;
+
+    private Set<String> ignoreTableName;
+    @Autowired
+    public MybatisPlusConfig(TenantIdManager tenantIdManager) {
+        this.tenantIdManager=tenantIdManager;
+        Set<Class<?>> classes = ClassUtil.scanPackage("com.coffee");
+        //找到所有@TableName修饰的类
+        tableClass = classes.stream().filter(aClass -> ObjectUtil.isNotNull(aClass.getAnnotation(TableName.class))).collect(Collectors.toList());
+        if (CollectionUtil.isNotEmpty(tableClass)) {
+            ignoreTableName =
+                    tableClass
+                            .stream()
+                            .filter(aClass -> aClass.getSuperclass() == TenantGenericEntity.class)
+                            .map(aClass -> {
+                                TableName tableName = aClass.getAnnotation(TableName.class);
+                                return tableName.value();
+                            })
+                            .collect(Collectors.toSet());
+        }
+        ignoreTableName = Optional.ofNullable(ignoreTableName).orElse(new HashSet<>());
+        ignoreTableName.addAll(classes
+                .stream()
+                .filter(aClass -> ObjectUtil.isNull(aClass.getAnnotation(TableName.class)))
+                .map(aClass -> StrUtil.toUnderlineCase(aClass.getSimpleName()))
+                .collect(Collectors.toSet()));
+    }
+
     @Bean
     @Bean
     public MybatisPlusInterceptor mybatisPlusInterceptor() {
     public MybatisPlusInterceptor mybatisPlusInterceptor() {
         MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
         MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
@@ -32,6 +85,8 @@ public class MybatisPlusConfig {
         interceptor.addInnerInterceptor(paginationInnerInterceptor());
         interceptor.addInnerInterceptor(paginationInnerInterceptor());
         // 乐观锁插件
         // 乐观锁插件
         interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
         interceptor.addInnerInterceptor(optimisticLockerInnerInterceptor());
+        //多租户插件
+        interceptor.addInnerInterceptor(tenantLineInnerInterceptor());
         return interceptor;
         return interceptor;
     }
     }
 
 
@@ -64,6 +119,40 @@ public class MybatisPlusConfig {
         return new OptimisticLockerInnerInterceptor();
         return new OptimisticLockerInnerInterceptor();
     }
     }
 
 
+    /**
+     * 多租户插件
+     */
+    public TenantLineInnerInterceptor tenantLineInnerInterceptor() {
+        TenantLineInnerInterceptor tenantInterceptor = new TenantLineInnerInterceptor();
+        tenantInterceptor.setTenantLineHandler(new TenantLineHandler() {
+            @Override
+            public Expression getTenantId() {
+                return new StringValue(tenantIdManager.getCurrentTenantId());
+            }
+
+            @Override
+            public String getTenantIdColumn() {
+                return null;
+            }
+
+            @Override
+            public boolean ignoreTable(String tableName) {
+                ServletRequestAttributes request = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+                //非用户请求,即来自程序自身,则忽略
+                if(request==null){
+                    return true;
+                }
+                return CollectionUtil.isEmpty(ignoreTableName)||ignoreTableName.contains(tableName);
+            }
+
+            @Override
+            public boolean ignoreInsert(List<Column> columns, String tenantIdColumn) {
+                return false;
+            }
+        });
+        return tenantInterceptor;
+    }
+
     /**
     /**
      * 元对象字段填充控制器
      * 元对象字段填充控制器
      */
      */

+ 32 - 0
coffee-framework/src/main/java/com/coffee/framework/config/mybatisplus/TenantIdManager.java

@@ -0,0 +1,32 @@
+package com.coffee.framework.config.mybatisplus;
+
+import cn.dev33.satoken.spring.SpringMVCUtil;
+import cn.dev33.satoken.stp.StpUtil;
+import com.coffee.common.Constants;
+import com.coffee.common.bo.LoginUser;
+import org.springframework.stereotype.Component;
+import org.springframework.web.context.request.RequestContextHolder;
+import org.springframework.web.context.request.ServletRequestAttributes;
+
+import javax.servlet.http.HttpServletRequest;
+
+/**
+ * 管理当前用户的租户ID
+ */
+@Component
+public class TenantIdManager {
+    /**
+     * 返回当前用户租户ID
+     * @return
+     */
+    public String getCurrentTenantId() {
+        //判断是否为request请求
+        ServletRequestAttributes request = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
+        if(request==null){
+            return "";
+        }
+        LoginUser loginUser = (LoginUser) StpUtil.getTokenSession().get(Constants.LOGIN_USER_KEY);
+        return  loginUser.getSysUser().getDeptId();
+    }
+
+}

+ 1 - 0
coffee-framework/src/main/java/com/coffee/framework/datasource/DynamicDataSource.java

@@ -1,5 +1,6 @@
 package com.coffee.framework.datasource;
 package com.coffee.framework.datasource;
 
 
+import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
 import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
 
 
 import javax.sql.DataSource;
 import javax.sql.DataSource;

+ 3 - 1
coffee-framework/src/main/java/com/coffee/framework/test/entity/Test.java

@@ -19,9 +19,10 @@ import java.util.Date;
  */
  */
 @TableName("test")
 @TableName("test")
 @Data
 @Data
-public class Test extends GenericEntity<String> implements Entity,RecordCreationEntity, RecordModifierEntity {
+public class Test extends GenericEntity<String> implements RecordCreationEntity, RecordModifierEntity {
 
 
     @Override
     @Override
+
     public String getId() {
     public String getId() {
         return super.getId();
         return super.getId();
     }
     }
@@ -32,6 +33,7 @@ public class Test extends GenericEntity<String> implements Entity,RecordCreation
 
 
     @TableField("nick_name")
     @TableField("nick_name")
     private String nickName;
     private String nickName;
+
     /**
     /**
      * 创建人
      * 创建人
      */
      */