Browse Source

增加数据库切换功能

zhou-hao 6 years ago
parent
commit
0c19fc515b

+ 14 - 3
hsweb-datasource/hsweb-datasource-api/src/main/java/org/hswebframework/web/datasource/DataSourceHolder.java

@@ -1,9 +1,8 @@
 package org.hswebframework.web.datasource;
 
+import org.hswebframework.ezorm.core.Database;
 import org.hswebframework.web.datasource.exception.DataSourceNotFoundException;
-import org.hswebframework.web.datasource.switcher.DataSourceSwitcher;
-import org.hswebframework.web.datasource.switcher.DefaultDataSourceSwitcher;
-import org.hswebframework.web.datasource.switcher.TableSwitcher;
+import org.hswebframework.web.datasource.switcher.*;
 
 /**
  * 用于操作动态数据源,如获取当前使用的数据源,使用switcher切换数据源等
@@ -26,6 +25,9 @@ public final class DataSourceHolder {
 
     static volatile TableSwitcher tableSwitcher;
 
+    static volatile DatabaseSwitcher databaseSwitcher=new DefaultDatabaseSwitcher();
+
+
     public static void checkDynamicDataSourceReady() {
         if (dynamicDataSourceService == null) {
             throw new UnsupportedOperationException("dataSourceService not ready");
@@ -46,6 +48,15 @@ public final class DataSourceHolder {
         return tableSwitcher;
     }
 
+    /**
+     * @return 数据库切换器
+     * @since 3.0.8
+     */
+    public static DatabaseSwitcher databaseSwitcher() {
+        return databaseSwitcher;
+    }
+
+
     /**
      * @return 默认数据源
      */

+ 4 - 0
hsweb-datasource/hsweb-datasource-api/src/main/java/org/hswebframework/web/datasource/DynamicDataSourceAutoConfiguration.java

@@ -6,6 +6,7 @@ import org.hswebframework.web.datasource.config.InSpringDynamicDataSourceConfig;
 import org.hswebframework.web.datasource.service.InSpringContextDynamicDataSourceService;
 import org.hswebframework.web.datasource.service.InSpringDynamicDataSourceConfigRepository;
 import org.hswebframework.web.datasource.switcher.DataSourceSwitcher;
+import org.hswebframework.web.datasource.switcher.DatabaseSwitcher;
 import org.hswebframework.web.datasource.switcher.DefaultTableSwitcher;
 import org.hswebframework.web.datasource.switcher.TableSwitcher;
 import org.springframework.beans.BeansException;
@@ -86,6 +87,9 @@ public class DynamicDataSourceAutoConfiguration {
                 if (bean instanceof TableSwitcher) {
                     DataSourceHolder.tableSwitcher = ((TableSwitcher) bean);
                 }
+                if (bean instanceof DatabaseSwitcher) {
+                    DataSourceHolder.databaseSwitcher = ((DatabaseSwitcher) bean);
+                }
                 return bean;
             }
         };

+ 28 - 0
hsweb-datasource/hsweb-datasource-api/src/main/java/org/hswebframework/web/datasource/switcher/DatabaseSwitcher.java

@@ -0,0 +1,28 @@
+package org.hswebframework.web.datasource.switcher;
+
+public interface DatabaseSwitcher {
+    /**
+     * 使用上一次调用的数据源
+     */
+    void useLast();
+
+    /**
+     * @param database 数据库名称
+     */
+    void use(String database);
+
+    /**
+     * 切换为默认数据库
+     */
+    void useDefault();
+
+    /**
+     * @return 当前选择的数据库
+     */
+    String currentDatabase();
+
+    /**
+     * 重置切换记录,重置后,使用默认数据库
+     */
+    void reset();
+}

+ 83 - 0
hsweb-datasource/hsweb-datasource-api/src/main/java/org/hswebframework/web/datasource/switcher/DefaultDatabaseSwitcher.java

@@ -0,0 +1,83 @@
+package org.hswebframework.web.datasource.switcher;
+
+import org.hswebframework.web.ThreadLocalUtils;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import java.util.Deque;
+import java.util.LinkedList;
+
+/**
+ * 默认的动态数据库切换器,基于ThreadLocal,queue
+ *
+ * @author zhouhao
+ * @since 3.0.8
+ */
+public class DefaultDatabaseSwitcher implements DatabaseSwitcher {
+
+    //默认数据源标识
+    private static final String DEFAULT_DATASOURCE_ID = DatabaseSwitcher.class.getName() + "_default_";
+
+    private Logger logger = LoggerFactory.getLogger(this.getClass());
+
+    private Deque<String> getUsedHistoryQueue() {
+        // 从ThreadLocal中获取一个使用记录
+        return ThreadLocalUtils.get(DefaultDatabaseSwitcher.class.getName() + "_queue", LinkedList::new);
+    }
+
+    @Override
+    public void useLast() {
+        // 没有上一次了
+        if (getUsedHistoryQueue().isEmpty()) {
+            return;
+        }
+        //移除队尾,则当前的队尾则为上一次的数据源
+        getUsedHistoryQueue().removeLast();
+        if (logger.isDebugEnabled()) {
+            String current = currentDatabase();
+            if (null != current) {
+                logger.debug("try use database : {}", currentDatabase());
+            } else {
+                logger.debug("try use last default database");
+            }
+        }
+    }
+
+    @Override
+    public void use(String dataSourceId) {
+        //添加对队尾
+        getUsedHistoryQueue().addLast(dataSourceId);
+        if (logger.isDebugEnabled()) {
+            logger.debug("try use datasource : {}", dataSourceId);
+        }
+    }
+
+    @Override
+    public void useDefault() {
+        getUsedHistoryQueue().addLast(DEFAULT_DATASOURCE_ID);
+        if (logger.isDebugEnabled()) {
+            logger.debug("try use default database");
+        }
+    }
+
+    @Override
+    public String currentDatabase() {
+        if (getUsedHistoryQueue().isEmpty()) {
+            return null;
+        }
+
+        String activeId = getUsedHistoryQueue().getLast();
+        if (DEFAULT_DATASOURCE_ID.equals(activeId)) {
+            return null;
+        }
+        return activeId;
+    }
+
+    @Override
+    public void reset() {
+        getUsedHistoryQueue().clear();
+        if (logger.isDebugEnabled()) {
+            logger.debug("reset database used history");
+        }
+    }
+}