Browse Source

在SQL层切换租户数据源

韩帛霖 1 year ago
parent
commit
2913b85aaa

+ 1 - 2
ruoyi-admin/src/main/java/com/ruoyi/web/controller/dragForm/CommonController.java

@@ -123,11 +123,10 @@ public class CommonController extends BaseController {
      * 动态表单预览接口
      */
     @GetMapping("/dragTablePreview")
-    public TableDataInfo DragTablePreview(CommonEntity commonEntity){
+    public TableDataInfo DragTablePreview(CommonEntity commonEntity) {
         startPage();
         return getDataTable(commonService.dragTablePreview(commonEntity));
     }
 
 
-
 }

+ 8 - 0
ruoyi-admin/src/main/resources/application.yml

@@ -49,6 +49,9 @@ user:
 
 # Spring配置
 spring:
+  # 开启AOP切面理论拦截
+  aop:
+    auto: true
   # 格式化时间
   jackson:
     date-format: yyyy-MM-dd HH:mm:ss
@@ -73,6 +76,11 @@ spring:
     restart:
       # 热部署开关
       enabled: true
+
+
+
+
+
   # redis 配置
   redis:
     # 地址

+ 11 - 10
ruoyi-admin/src/main/resources/mybatis/mybatis-config.xml

@@ -1,27 +1,28 @@
 <?xml version="1.0" encoding="UTF-8" ?>
 <!DOCTYPE configuration
-PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
-"http://mybatis.org/dtd/mybatis-3-config.dtd">
+        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
+        "http://mybatis.org/dtd/mybatis-3-config.dtd">
 <configuration>
     <!-- 全局参数 -->
     <settings>
         <!-- 使全局的映射器启用或禁用缓存 -->
-        <setting name="cacheEnabled"             value="true"   />
+        <setting name="cacheEnabled" value="true"/>
         <!-- 允许JDBC 支持自动生成主键 -->
-        <setting name="useGeneratedKeys"         value="true"   />
+        <setting name="useGeneratedKeys" value="true"/>
         <!-- 配置默认的执行器.SIMPLE就是普通执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 -->
-        <setting name="defaultExecutorType"      value="SIMPLE" />
-		<!-- 指定 MyBatis 所用日志的具体实现 -->
-        <setting name="logImpl"                  value="SLF4J"  />
+        <setting name="defaultExecutorType" value="SIMPLE"/>
+        <!-- 指定 MyBatis 所用日志的具体实现 -->
+        <setting name="logImpl" value="SLF4J"/>
         <!-- 使用驼峰命名法转换字段 -->
         <setting name="mapUnderscoreToCamelCase" value="true"/>
         <!-- value为空时显示key -->
-        <setting name="callSettersOnNulls" value="true" />
+        <setting name="callSettersOnNulls" value="true"/>
 
         <setting name="mapUnderscoreToCamelCase" value="true"/>
     </settings>
     <!--  重写驼峰转换工具类  -->
     <objectWrapperFactory type="com.ruoyi.common.utils.MapWrapperFactory"/>
-
-
+    <plugins>
+        <plugin interceptor="com.ruoyi.framework.aspectj.SqlInterceptor"/>
+    </plugins>
 </configuration>

+ 51 - 0
ruoyi-framework/src/main/java/com/ruoyi/framework/aspectj/SqlInterceptor.java

@@ -0,0 +1,51 @@
+package com.ruoyi.framework.aspectj;
+
+import com.ruoyi.common.utils.SecurityUtils;
+import com.ruoyi.common.utils.reflect.ReflectUtils;
+import org.apache.ibatis.executor.statement.StatementHandler;
+import org.apache.ibatis.plugin.*;
+
+import java.sql.Connection;
+import java.util.Properties;
+
+/**
+ * AOP 拦截SQL处理
+ *
+ * @author hzh
+ */
+@Intercepts({
+        @Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})
+})
+public class SqlInterceptor implements Interceptor {
+
+    @Override
+    public Object intercept(Invocation invocation) throws Throwable {
+        StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
+        String sql = statementHandler.getBoundSql().getSql();
+        // 修改SQL语句
+        String modifiedSql = modifySql(sql);
+        // 将修改后的SQL语句设置回StatementHandler
+        ReflectUtils.setFieldValue(statementHandler.getBoundSql(), "sql", modifiedSql);
+        return invocation.proceed();
+    }
+
+    // 根据类型设置不同的选择数据源格式
+    private String modifySql(String sql) {
+        if (SecurityUtils.getDatabaseType().equals("sqlserver"))
+            return "USE `" + SecurityUtils.getDatabaseName() + "`; " + sql;
+        if (SecurityUtils.getDatabaseType().equals("dm"))
+            return "set schema " + SecurityUtils.getDatabaseName() + "; " + sql;
+        if (SecurityUtils.getDatabaseType().equals("mysql"))
+            return "USE `" + SecurityUtils.getDatabaseName() + "`; " + sql;
+        return "";
+    }
+
+    @Override
+    public Object plugin(Object target) {
+        return Plugin.wrap(target, this);
+    }
+
+    @Override
+    public void setProperties(Properties properties) {
+    }
+}

+ 23 - 45
ruoyi-framework/src/main/java/com/ruoyi/framework/config/MyBatisConfig.java

@@ -6,6 +6,7 @@ import java.util.Arrays;
 import java.util.HashSet;
 import java.util.List;
 import javax.sql.DataSource;
+
 import org.apache.ibatis.io.VFS;
 import org.apache.ibatis.session.SqlSessionFactory;
 import org.mybatis.spring.SqlSessionFactoryBean;
@@ -26,86 +27,63 @@ import com.ruoyi.common.utils.StringUtils;
 
 /**
  * Mybatis支持*匹配扫描包
- * 
+ *
  * @author ruoyi
  */
 @Configuration
-public class MyBatisConfig
-{
+public class MyBatisConfig {
     @Autowired
     private Environment env;
-
     static final String DEFAULT_RESOURCE_PATTERN = "**/*.class";
 
-    public static String setTypeAliasesPackage(String typeAliasesPackage)
-    {
+    public static String setTypeAliasesPackage(String typeAliasesPackage) {
         ResourcePatternResolver resolver = (ResourcePatternResolver) new PathMatchingResourcePatternResolver();
         MetadataReaderFactory metadataReaderFactory = new CachingMetadataReaderFactory(resolver);
         List<String> allResult = new ArrayList<String>();
-        try
-        {
-            for (String aliasesPackage : typeAliasesPackage.split(","))
-            {
+        try {
+            for (String aliasesPackage : typeAliasesPackage.split(",")) {
                 List<String> result = new ArrayList<String>();
                 aliasesPackage = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX
                         + ClassUtils.convertClassNameToResourcePath(aliasesPackage.trim()) + "/" + DEFAULT_RESOURCE_PATTERN;
                 Resource[] resources = resolver.getResources(aliasesPackage);
-                if (resources != null && resources.length > 0)
-                {
+                if (resources != null && resources.length > 0) {
                     MetadataReader metadataReader = null;
-                    for (Resource resource : resources)
-                    {
-                        if (resource.isReadable())
-                        {
+                    for (Resource resource : resources) {
+                        if (resource.isReadable()) {
                             metadataReader = metadataReaderFactory.getMetadataReader(resource);
-                            try
-                            {
+                            try {
                                 result.add(Class.forName(metadataReader.getClassMetadata().getClassName()).getPackage().getName());
-                            }
-                            catch (ClassNotFoundException e)
-                            {
+                            } catch (ClassNotFoundException e) {
                                 e.printStackTrace();
                             }
                         }
                     }
                 }
-                if (result.size() > 0)
-                {
+                if (result.size() > 0) {
                     HashSet<String> hashResult = new HashSet<String>(result);
                     allResult.addAll(hashResult);
                 }
             }
-            if (allResult.size() > 0)
-            {
+            if (allResult.size() > 0) {
                 typeAliasesPackage = String.join(",", (String[]) allResult.toArray(new String[0]));
-            }
-            else
-            {
+            } else {
                 throw new RuntimeException("mybatis typeAliasesPackage 路径扫描错误,参数typeAliasesPackage:" + typeAliasesPackage + "未找到任何包");
             }
-        }
-        catch (IOException e)
-        {
+        } catch (IOException e) {
             e.printStackTrace();
         }
         return typeAliasesPackage;
     }
 
-    public Resource[] resolveMapperLocations(String[] mapperLocations)
-    {
+    public Resource[] resolveMapperLocations(String[] mapperLocations) {
         ResourcePatternResolver resourceResolver = new PathMatchingResourcePatternResolver();
         List<Resource> resources = new ArrayList<Resource>();
-        if (mapperLocations != null)
-        {
-            for (String mapperLocation : mapperLocations)
-            {
-                try
-                {
+        if (mapperLocations != null) {
+            for (String mapperLocation : mapperLocations) {
+                try {
                     Resource[] mappers = resourceResolver.getResources(mapperLocation);
                     resources.addAll(Arrays.asList(mappers));
-                }
-                catch (IOException e)
-                {
+                } catch (IOException e) {
                     // ignore
                 }
             }
@@ -114,8 +92,7 @@ public class MyBatisConfig
     }
 
     @Bean
-    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception
-    {
+    public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
         String typeAliasesPackage = env.getProperty("mybatis.typeAliasesPackage");
         String mapperLocations = env.getProperty("mybatis.mapperLocations");
         String configLocation = env.getProperty("mybatis.configLocation");
@@ -129,4 +106,5 @@ public class MyBatisConfig
         sessionFactory.setConfigLocation(new DefaultResourceLoader().getResource(configLocation));
         return sessionFactory.getObject();
     }
-}
+}
+

+ 1 - 1
ruoyi-framework/src/main/java/com/ruoyi/framework/web/service/TokenService.java

@@ -193,7 +193,7 @@ public class TokenService {
      * @return token
      */
     private String getToken(HttpServletRequest request) {
-        System.err.println("当前请求方式:" + request.getMethod());
+//        System.err.println("当前请求方式:" + request.getMethod());
         String token = request.getHeader(header);
         if (StringUtils.isNotEmpty(token) && token.startsWith(Constants.TOKEN_PREFIX)) {
             token = token.replace(Constants.TOKEN_PREFIX, "");

+ 4 - 3
ruoyi-system/src/main/java/com/ruoyi/system/service/impl/DragTableServiceImpl.java

@@ -6,6 +6,7 @@ import java.util.stream.Collectors;
 
 import com.alibaba.fastjson2.JSON;
 import com.ruoyi.common.utils.DateUtils;
+import com.ruoyi.common.utils.SecurityUtils;
 import com.ruoyi.common.utils.uuid.IdUtils;
 import com.ruoyi.system.entity.CommonEntity;
 import com.ruoyi.system.entity.DragTable;
@@ -186,14 +187,14 @@ public class DragTableServiceImpl implements IDragTableService {
                     SQL_START += dragTableVo.getSearchFieldList().size() - 1 == i ? " " : "||";
                 }
                 break;
-            }
+        }
         tableSql.setTableCondition(SQL_START + SQL_END);
         tableSql.setTableAlias(dragTableVo.getDtTableName());
         tableSql.setSqlKey(sqlKey);
         tableSql.setTableExportField(JSON.toJSONString(dragTableVo.getTableExportField()));
         tableSqlMapper.insertTableSql(tableSql);
         //add drag_table_condition
-        if(dragTableVo.getSearchFieldList().size() > 0 ){
+        if (dragTableVo.getSearchFieldList().size() > 0) {
             List<DragTableCondition> dragTableConditionList = new ArrayList<>();
             dragTableVo.getSearchFieldList().forEach(item -> {
                 dragTableConditionList.add(new DragTableCondition(dragTable.gettId(), item));
@@ -251,7 +252,7 @@ public class DragTableServiceImpl implements IDragTableService {
         tableSqlMapper.updateTableSqlBySqlKey(tableSql);
 
         //update drag_table_condition
-        if(dragTableVo.getSearchFieldList().size() > 0){
+        if (dragTableVo.getSearchFieldList().size() > 0) {
             //delete
             dragTableConditionMapper.deleteDragTableConditionBytIds(Collections.singletonList(dragTableVo.gettId()));
             //insert