ltkj-admin/src/main/java/com/ltkj/web/db/DataSourceConfig.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ltkj-admin/src/main/java/com/ltkj/web/db/DataSourceContextHolder.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 | |
ltkj-admin/src/main/java/com/ltkj/web/db/DynamicDataSource.java | ●●●●● 补丁 | 查看 | 原始文档 | blame | 历史 |
ltkj-admin/src/main/java/com/ltkj/web/db/DataSourceConfig.java
New file @@ -0,0 +1,63 @@ package com.ltkj.web.db; import com.alibaba.druid.pool.DruidDataSource; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; @Configuration public class DataSourceConfig { private static final String DEFAULT_DATA_SOURCE_KEY = "default"; // 主库的标识 private final Map<String, DataSource> dataSourceCache = new HashMap<>(); // 数据源缓存 // 从 application.yml 中读取主库的配置 @Value("${spring.datasource.url}") private String primaryUrl; @Value("${spring.datasource.username}") private String primaryUsername; @Value("${spring.datasource.password}") private String primaryPassword; @Value("${dbUrl}") private String dbUrl; @Bean public DataSource dynamicDataSource() { DynamicDataSource dynamicDataSource = new DynamicDataSource(); // 初始化默认数据源为主库 dynamicDataSource.addTargetDataSource(DEFAULT_DATA_SOURCE_KEY, createDataSource(primaryUrl, primaryUsername, primaryPassword)); dynamicDataSource.setDefaultTargetDataSource(dynamicDataSource.getTargetDataSources().get(DEFAULT_DATA_SOURCE_KEY)); // 设置默认数据源 return dynamicDataSource; } // 动态创建数据源 private DataSource createDataSource(String url, String username, String password) { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUrl(url); dataSource.setUsername(username); dataSource.setPassword(password); return dataSource; } // 根据用户 ID 动态获取数据源 public void addDataSource(String userId) { String dbName = "scum_admin_user_" + userId; // 检查缓存中是否已经存在该数据源 if (!dataSourceCache.containsKey(userId)) { String url = "jdbc:mysql://"+dbUrl+":3306/"+dbName; DataSource dataSource = createDataSource(url, primaryUsername, primaryPassword); dataSourceCache.put(userId, dataSource); DynamicDataSource dynamicDataSource = (DynamicDataSource) dynamicDataSource(); dynamicDataSource.addTargetDataSource(userId, dataSource); } } } ltkj-admin/src/main/java/com/ltkj/web/db/DataSourceContextHolder.java
New file @@ -0,0 +1,17 @@ package com.ltkj.web.db; public class DataSourceContextHolder { private static final ThreadLocal<String> contextHolder = new ThreadLocal<>(); public static void setDataSourceKey(String key) { contextHolder.set(key); } public static String getDataSourceKey() { return contextHolder.get(); } public static void clear() { contextHolder.remove(); } } ltkj-admin/src/main/java/com/ltkj/web/db/DynamicDataSource.java
New file @@ -0,0 +1,34 @@ package com.ltkj.web.db; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import javax.sql.DataSource; import java.util.HashMap; import java.util.Map; public class DynamicDataSource extends AbstractRoutingDataSource { private final Map<Object, Object> targetDataSources = new HashMap<>(); // 存储所有数据源 @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSourceKey(); // 根据上下文获取当前数据源的键 } // 添加目标数据源 public void addTargetDataSource(String key, DataSource dataSource) { targetDataSources.put(key, dataSource); super.setTargetDataSources(targetDataSources); // 更新目标数据源 super.afterPropertiesSet(); // 重新初始化数据源 } // 允许外部访问所有目标数据源 @Override public void setTargetDataSources(Map<Object, Object> targetDataSources) { super.setTargetDataSources(targetDataSources); } public Map<Object, Object> getTargetDataSources() { return targetDataSources; // 获取所有目标数据源 } }