ltkj-admin/src/main/java/com/ltkj/web/controller/system/SysRoleController.java
@@ -1,10 +1,30 @@ package com.ltkj.web.controller.system; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStreamReader; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.servlet.http.HttpServletResponse; import cn.hutool.core.util.IdUtil; import cn.hutool.core.util.RandomUtil; import com.ltkj.db.DataSourceConfig; import com.ltkj.db.DataSourceContextHolder; import com.ltkj.hosp.domain.DictHosp; import com.ltkj.hosp.service.IDictHospService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.io.ClassPathResource; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.util.FileCopyUtils; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.DeleteMapping; import org.springframework.web.bind.annotation.GetMapping; @@ -55,6 +75,13 @@ @Autowired private ISysDeptService deptService; @Autowired private JdbcTemplate jdbcTemplate; @Autowired private IDictHospService dictHospService; @Value("${config.path}") private String path; // @PreAuthorize("@ss.hasPermi('system:role:list')") @GetMapping("/list") @@ -245,4 +272,54 @@ ajax.put("depts", deptService.selectDeptTreeList(new SysDept())); return ajax; } @Autowired private DataSourceConfig dataSourceConfig; /** * 从库批量执行sql * 读取本地sql文件 * @return */ @GetMapping("/execUpdateSql") public AjaxResult execUpdateSql() { DataSourceContextHolder.setDataSourceKey("default"); List<DictHosp> list = dictHospService.list(); List<Map<String, Object>> resultList = new ArrayList<>(); for (DictHosp dictHosp : list) { String dbName = dictHosp.getDbname(); Map<String, Object> dbResult = new HashMap<>(); dbResult.put("database", dbName); List<String> successList = new ArrayList<>(); List<String> errorList = new ArrayList<>(); try { InputStreamReader reader = new InputStreamReader(Files.newInputStream(Paths.get(path + File.separator + "update.sql")), StandardCharsets.UTF_8); String sqlContent = FileCopyUtils.copyToString(reader); String[] sqlStatements = sqlContent.split("\\|-\\|"); for (String sql : sqlStatements) { sql = sql.trim(); if (!sql.isEmpty()) { // INSERT INTO `api_config` (`id`, `api_url`, `api_method`, `tab_name`, `is_response`, `primary_keys`, `remark`, `result_code_key`, `result_data_key`, `type`) VALUES (${id}, '${dbName}', '${randowmStr}', '${randowmStr}', 1, 'ResultData', '1.pas 检查申请信息作废', 'ResultCode', 'ResultData', 'pacs'); // sql = sql.replace("${dbName}",dbName).replace("${id}", IdUtil.getSnowflake().nextIdStr()).replace("${randowmStr}", RandomUtil.randomString(10)); try { dataSourceConfig.addDataSource(dbName); DataSourceContextHolder.setDataSourceKey(dbName); jdbcTemplate.execute(sql); successList.add(sql); } catch (Exception e) { errorList.add(sql + " -> ERROR: " + e.getMessage()); } } } } catch (IOException e) { return AjaxResult.error("读取SQL文件失败:" + e.getMessage()); } dbResult.put("successSQL", successList); dbResult.put("failedSQL", errorList); resultList.add(dbResult); } DataSourceContextHolder.clear(); return AjaxResult.success(resultList); } } ltkj-framework/src/main/java/com/ltkj/framework/aspectj/DataSourceAspect.java
@@ -2,6 +2,7 @@ import java.util.Objects; import com.ltkj.db.DataSourceContextHolder; import com.ltkj.framework.datasource.DynamicDataSourceContextHolder; import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; @@ -38,14 +39,14 @@ DataSource dataSource = getDataSource(point); if (StringUtils.isNotNull(dataSource)) { DynamicDataSourceContextHolder.setDataSourceType(dataSource.value().name()); DataSourceContextHolder.setDataSourceKey(dataSource.value().name()); } try { return point.proceed(); } finally { // 销毁数据源 在执行方法之后 DynamicDataSourceContextHolder.clearDataSourceType(); DataSourceContextHolder.clear(); } } ltkj-framework/src/main/java/com/ltkj/framework/config/DruidConfig.java
@@ -35,7 +35,7 @@ * * @author ltkj */ @Configuration //@Configuration @Slf4j public class DruidConfig { @@ -69,7 +69,7 @@ private String dbName; @Bean // @Bean // @ConfigurationProperties("spring.datasource.druid.master") public DataSource masterDataSource(DruidProperties druidProperties) { DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); @@ -150,7 +150,7 @@ return druidProperties.dataSource(dataSource); } @Bean // @Bean // @ConfigurationProperties("spring.datasource.druid.slavehis") // @ConditionalOnProperty(prefix = "spring.datasource.druid.slavehis", name = "enabled", havingValue = "true") public DataSource slaveHisDataSource(DruidProperties druidProperties) { @@ -193,7 +193,7 @@ return druidProperties.dataSource(dataSource); } @Bean // @Bean // @ConfigurationProperties("spring.datasource.druid.slavelis") // @ConditionalOnProperty(prefix = "spring.datasource.druid.slavelis", name = "enabled", havingValue = "true") public DataSource slaveDataLisSource(DruidProperties druidProperties) { @@ -235,7 +235,7 @@ return druidProperties.dataSource(dataSource); } @Bean // @Bean // @ConfigurationProperties("spring.datasource.druid.slavepacs") // @ConditionalOnProperty(prefix = "spring.datasource.druid.slavepacs", name = "enabled", havingValue = "true") public DataSource slaveDataPacsSource(DruidProperties druidProperties) { @@ -278,7 +278,7 @@ return druidProperties.dataSource(dataSource); } @Bean // @Bean // @ConfigurationProperties("spring.datasource.druid.slavepacs") // @ConditionalOnProperty(prefix = "spring.datasource.druid.slavepacs", name = "enabled", havingValue = "true") public DataSource slaveDataWsSource(DruidProperties druidProperties) { @@ -427,8 +427,8 @@ } @Bean(name = "dynamicDataSource") @Primary // @Bean(name = "dynamicDataSource") // @Primary public DynamicDataSource dataSource(DataSource masterDataSource) { Map<Object, Object> targetDataSources = new HashMap<>(); targetDataSources.put(DataSourceType.MASTER.name(), masterDataSource); @@ -458,8 +458,8 @@ * 去除监控页面底部的广告 */ @SuppressWarnings({"rawtypes", "unchecked"}) @Bean @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true") // @Bean // @ConditionalOnProperty(name = "spring.datasource.druid.statViewServlet.enabled", havingValue = "true") public FilterRegistrationBean removeDruidFilterRegistrationBean(DruidStatProperties properties) { // 获取web监控页面的参数 DruidStatProperties.StatViewServlet config = properties.getStatViewServlet(); ltkj-framework/src/main/java/com/ltkj/framework/config/WebConfig.java
@@ -38,7 +38,8 @@ .excludePathPatterns(new String[]{ "/system/dict/data/**", "/system/dict/type/**", "/captchaImage","/getCaptchaConfigKey/**" "/captchaImage","/getCaptchaConfigKey/**", "/system/role/execUpdateSql" // , // "/login", "/register", "/captchaImage","/cus/**","/getCaptchaConfigKey","/report/jmreport/**", // "/sqlserver/getdata/**","/api/His/**","/system/config/zx","/system/config/gxxmpym","/system/report/savePdf", ltkj-framework/src/main/java/com/ltkj/framework/datasource/DynamicDataSourceContextHolder.java
@@ -1,5 +1,6 @@ package com.ltkj.framework.datasource; import com.ltkj.db.DataSourceContextHolder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -22,20 +23,23 @@ */ public static void setDataSourceType(String dsType) { log.info("切换到{}数据源", dsType); CONTEXT_HOLDER.set(dsType); // CONTEXT_HOLDER.set(dsType); DataSourceContextHolder.setDataSourceKey(dsType); } /** * 获得数据源的变量 */ public static String getDataSourceType() { return CONTEXT_HOLDER.get(); // return CONTEXT_HOLDER.get(); return DataSourceContextHolder.getDataSourceKey(); } /** * 清空数据源变量 */ public static void clearDataSourceType() { CONTEXT_HOLDER.remove(); // CONTEXT_HOLDER.remove(); DataSourceContextHolder.clear(); } } ltkj-framework/src/main/java/com/ltkj/framework/interceptor/DBChangeInterceptor.java
@@ -29,10 +29,10 @@ @Autowired private IDictHospService dictHospService; // @Autowired // private DataSourceConfig dataSourceConfig; @Autowired private DruidConfig druidConfig; private DataSourceConfig dataSourceConfig; // @Autowired // private DruidConfig druidConfig; @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws IOException { @@ -55,8 +55,8 @@ response.getWriter().write("{\"message\":\"401:找不到院区数据\"}"); return false; } // dataSourceConfig.addDataSource(hosp.getDbname()); druidConfig.addDataSource(hosp.getDbname()); dataSourceConfig.addDataSource(hosp.getDbname()); // druidConfig.addDataSource(hosp.getDbname()); DataSourceContextHolder.setDataSourceKey(hosp.getDbname()); } catch (IOException e) { return false; ltkj-hosp/pom.xml
@@ -28,6 +28,12 @@ <dependency> <groupId>com.ltkj</groupId> <artifactId>ltkj-common</artifactId> <exclusions> <exclusion> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </exclusion> </exclusions> </dependency> <!-- 集成积木报表--> @@ -35,6 +41,12 @@ <groupId>org.jeecgframework.jimureport</groupId> <artifactId>jimureport-spring-boot-starter</artifactId> <version>1.5.4</version> <exclusions> <exclusion> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </exclusion> </exclusions> </dependency> <!-- 阿里数据库连接池 --> @@ -43,6 +55,11 @@ <artifactId>druid-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </dependency> </dependencies> </project> ltkj-hosp/src/main/java/com/ltkj/db/DataSourceConfig.java
@@ -1,20 +1,23 @@ package com.ltkj.db; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceBuilder; import com.ltkj.common.enums.DataSourceType; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; 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.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.*; import java.sql.SQLException; import java.util.HashMap; import java.util.Map; import java.util.Properties; //@Configuration @Slf4j @Configuration public class DataSourceConfig { private static final String DEFAULT_DATA_SOURCE_KEY = "default"; // 主库的标识 @@ -64,6 +67,13 @@ // 初始化默认数据源为主库 dynamicDataSource.addTargetDataSource(DEFAULT_DATA_SOURCE_KEY, createDataSource(url, primaryUsername, primaryPassword)); DruidProperties properties = new DruidProperties(); dynamicDataSource.addTargetDataSource(DataSourceType.MASTER.name(),masterDataSource(properties)); dynamicDataSource.addTargetDataSource(DataSourceType.SLAVE_HIS.name(),slaveHisDataSource(properties)); dynamicDataSource.addTargetDataSource(DataSourceType.SLAVE_LIS.name(),slaveDataLisSource(properties)); dynamicDataSource.addTargetDataSource(DataSourceType.SLAVE_PACS.name(),slaveDataPacsSource(properties)); dynamicDataSource.addTargetDataSource(DataSourceType.SLAVE_WS.name(),slaveDataWsSource(properties)); dynamicDataSource.setDefaultTargetDataSource(dynamicDataSource.getTargetDataSources().get(DEFAULT_DATA_SOURCE_KEY)); // 设置默认数据源 return dynamicDataSource; } @@ -104,4 +114,233 @@ } } } private DataSource masterDataSource(DruidProperties druidProperties) { DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); Properties props = new Properties(); try { // 从文件中读取配置信息 FileInputStream fis = null; try { fis = new FileInputStream(url); } catch (FileNotFoundException e) { log.info("数据库连接文件找不到!"); } props.load(fis); fis.close(); // 获取属性值并赋值 String hisenabled = props.getProperty("hisenabled"); if (hisenabled.equals("false")) return null; dataSource = creatMysql(hisenabled, props.getProperty("ip"),props.getProperty("prot"),props.getProperty("name"),props.getProperty("username"),props.getProperty("password")); log.info("his数据库连接成功!!!"); } catch (Exception e) { log.info("数据库连接失败 请联系管理员!"); e.printStackTrace(); } return druidProperties.dataSource(dataSource); } private DataSource slaveHisDataSource(DruidProperties druidProperties) { DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); Properties props = new Properties(); try { // 从文件中读取配置信息 FileInputStream fis = null; try { fis = new FileInputStream(url); } catch (FileNotFoundException e) { log.info("数据库连接文件找不到!"); } props.load(fis); fis.close(); // 获取属性值并赋值 String hisenabled = props.getProperty("hisenabled"); if (hisenabled.equals("false")) return null; String hisdbtype = props.getProperty("hisdbtype"); switch (hisdbtype){ case "sqlserver": dataSource = creatSqlServer(hisenabled, props.getProperty("hisip"),props.getProperty("hisprot"),props.getProperty("hisname"),props.getProperty("hisusername"),props.getProperty("hispassword")); break; case "mysql": dataSource = creatMysql(hisenabled, props.getProperty("hisip"),props.getProperty("hisprot"),props.getProperty("hisname"),props.getProperty("hisusername"),props.getProperty("hispassword")); break; case "oracle": dataSource = creatOracle(hisenabled, props.getProperty("hisip"),props.getProperty("hisprot"),props.getProperty("hisname"),props.getProperty("hisusername"),props.getProperty("hispassword")); break; default: dataSource = creatSqlServer(hisenabled, props.getProperty("hisip"),props.getProperty("hisprot"),props.getProperty("hisname"),props.getProperty("hisusername"),props.getProperty("hispassword")); break; } log.info("his数据库连接成功!!!"); } catch (Exception e) { log.info("数据库连接失败 请联系管理员!"); e.printStackTrace(); } return druidProperties.dataSource(dataSource); } private DataSource slaveDataLisSource(DruidProperties druidProperties) { DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); Properties props = new Properties(); try { // 从文件中读取配置信息 FileInputStream fis = null; try { fis = new FileInputStream(url); } catch (FileNotFoundException e) { log.info("数据库连接文件找不到!"); } props.load(fis); fis.close(); String lisenabled = props.getProperty("lisenabled"); if (lisenabled.equals("false")) return null; String lisdbtype = props.getProperty("lisdbtype"); switch (lisdbtype){ case "sqlserver": dataSource = creatSqlServer(lisenabled, props.getProperty("lisip"),props.getProperty("lisprot"),props.getProperty("lisname"),props.getProperty("lisusername"),props.getProperty("lispassword")); break; case "mysql": dataSource = creatMysql(lisenabled, props.getProperty("lisip"),props.getProperty("lisprot"),props.getProperty("lisname"),props.getProperty("lisusername"),props.getProperty("lispassword")); break; case "oracle": dataSource = creatOracle(lisenabled, props.getProperty("lisip"),props.getProperty("lisprot"),props.getProperty("lisname"),props.getProperty("lisusername"),props.getProperty("lispassword")); break; default: dataSource = creatMysql(lisenabled, props.getProperty("lisip"),props.getProperty("lisprot"),props.getProperty("lisname"),props.getProperty("lisusername"),props.getProperty("lispassword")); break; } log.info("Lis数据库连接成功!!!"); } catch (Exception e) { log.info("数据库连接失败 请联系管理员!"); e.printStackTrace(); } return druidProperties.dataSource(dataSource); } private DataSource slaveDataPacsSource(DruidProperties druidProperties) { DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); Properties props = new Properties(); try { // 从文件中读取配置信息 FileInputStream fis = null; try { fis = new FileInputStream(url); } catch (FileNotFoundException e) { log.info("数据库连接文件找不到"); } props.load(fis); fis.close(); // 这里是测试写法,具体的value可以通过请求参数传递过来 String pacsenabled = props.getProperty("pacsenabled"); if (pacsenabled.equals("false")) return null; String pacsdbtype = props.getProperty("pacsdbtype"); switch (pacsdbtype){ case "sqlserver": dataSource = creatSqlServer(pacsenabled, props.getProperty("pacsip"),props.getProperty("pacsprot"),props.getProperty("pacsname"),props.getProperty("pacsusername"),props.getProperty("pacspassword")); break; case "mysql": dataSource = creatMysql(pacsenabled, props.getProperty("pacsip"),props.getProperty("pacsprot"),props.getProperty("pacsname"),props.getProperty("pacsusername"),props.getProperty("pacspassword")); break; case "oracle": dataSource = creatOracle(pacsenabled, props.getProperty("pacsip"),props.getProperty("pacsprot"),props.getProperty("pacsname"),props.getProperty("pacsusername"),props.getProperty("pacspassword")); break; default: dataSource = creatOracle(pacsenabled, props.getProperty("pacsip"),props.getProperty("pacsprot"),props.getProperty("pacsname"),props.getProperty("pacsusername"),props.getProperty("pacspassword")); break; } log.info("数据库连接成功!!!"); } catch (Exception e) { log.info("数据库连接失败 请联系管理员!"); e.printStackTrace(); } return druidProperties.dataSource(dataSource); } private DataSource slaveDataWsSource(DruidProperties druidProperties) { DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); Properties props = new Properties(); try { // 从文件中读取配置信息 FileInputStream fis = null; try { fis = new FileInputStream(url); } catch (FileNotFoundException e) { log.info("数据库连接文件找不到"); } props.load(fis); fis.close(); // 这里是测试写法,具体的value可以通过请求参数传递过来 String pacsenabled = props.getProperty("wsenabled"); if (pacsenabled.equals("false")) return null; String pacsdbtype = props.getProperty("wsdbtype"); switch (pacsdbtype){ case "sqlserver": dataSource = creatSqlServer(pacsenabled, props.getProperty("wsip"),props.getProperty("wsprot"), props.getProperty("wsname"),props.getProperty("wsusername"),props.getProperty("wspassword")); break; case "mysql": dataSource = creatMysql(pacsenabled, props.getProperty("wsip"), props.getProperty("wsprot"),props.getProperty("wsname"),props.getProperty("wsusername"),props.getProperty("wspassword")); break; case "oracle": dataSource = creatOracle(pacsenabled, props.getProperty("wsip"), props.getProperty("wsprot"),props.getProperty("wsname"),props.getProperty("wsusername"),props.getProperty("wspassword")); break; default: dataSource = creatOracle(pacsenabled, props.getProperty("wsip"),props.getProperty("wsprot"),props.getProperty("wsname"),props.getProperty("wsusername") ,props.getProperty("wspassword")); break; } log.info("数据库连接成功!!!"); } catch (Exception e) { log.info("数据库连接失败 请联系管理员!"); e.printStackTrace(); } return druidProperties.dataSource(dataSource); } private DruidDataSource creatSqlServer(String enabled, String ip,String port,String db,String user,String password) throws SQLException { DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); Properties properties = new Properties(); properties.setProperty("druid.enabled", enabled); properties.setProperty("druid.driverClassName","com.microsoft.sqlserver.jdbc.SQLServerDriver"); properties.setProperty("druid.url","jdbc:sqlserver://"+ ip+":"+ port+";DatabaseName="+ db+ ";&characterEncoding=utf8"); properties.setProperty("druid.username", user); properties.setProperty("druid.password", password); dataSource.restart(properties); return dataSource; } private DruidDataSource creatMysql(String enabled, String ip,String port,String db,String user,String password) throws SQLException { DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); Properties properties = new Properties(); properties.setProperty("druid.enabled",enabled); properties.setProperty("druid.url","jdbc:mysql://"+ip+":"+port+"/"+db+"" + "?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8"); properties.setProperty("druid.username",user); properties.setProperty("druid.password",password); dataSource.restart(properties); return dataSource; } private DruidDataSource creatOracle(String enabled, String ip,String port,String db,String user,String password) throws SQLException { DruidDataSource dataSource = DruidDataSourceBuilder.create().build(); Properties properties = new Properties(); properties.setProperty("druid.enabled",enabled); properties.setProperty("druid.driverClassName","oracle.jdbc.OracleDriver"); properties.setProperty("druid.url","jdbc:oracle:thin:@//"+ip+"/"+db); properties.setProperty("druid.username",user); properties.setProperty("druid.password",password); dataSource.restart(properties); return dataSource; } } ltkj-hosp/src/main/java/com/ltkj/db/DruidProperties.java
New file @@ -0,0 +1,61 @@ package com.ltkj.db; import com.alibaba.druid.pool.DruidDataSource; /** * druid 配置属性 * * @author ruoyi */ public class DruidProperties { private int initialSize=5; private int minIdle=10; private int maxActive=20; private int maxWait=60000; private int timeBetweenEvictionRunsMillis=60000; private int minEvictableIdleTimeMillis=300000; private int maxEvictableIdleTimeMillis=900000; private boolean testWhileIdle=true; private boolean testOnBorrow=false; private boolean testOnReturn=false; public DruidDataSource dataSource(DruidDataSource datasource) { /** 配置初始化大小、最小、最大 */ datasource.setInitialSize(initialSize); datasource.setMaxActive(maxActive); datasource.setMinIdle(minIdle); /** 配置获取连接等待超时的时间 */ datasource.setMaxWait(maxWait); /** 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 */ datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); /** 配置一个连接在池中最小、最大生存的时间,单位是毫秒 */ datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); datasource.setMaxEvictableIdleTimeMillis(maxEvictableIdleTimeMillis); /** * 用来检测连接是否有效的sql,要求是一个查询语句,常用select 'x'。如果validationQuery为null,testOnBorrow、testOnReturn、testWhileIdle都不会起作用。 */ // datasource.setValidationQuery(validationQuery); /** 建议配置为true,不影响性能,并且保证安全性。申请连接的时候检测,如果空闲时间大于timeBetweenEvictionRunsMillis,执行validationQuery检测连接是否有效。 */ datasource.setTestWhileIdle(testWhileIdle); /** 申请连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */ datasource.setTestOnBorrow(testOnBorrow); /** 归还连接时执行validationQuery检测连接是否有效,做了这个配置会降低性能。 */ datasource.setTestOnReturn(testOnReturn); return datasource; } } ltkj-hosp/src/main/java/com/ltkj/db/HospDynamicDataSource.java
@@ -1,25 +1,31 @@ package com.ltkj.db; import lombok.extern.slf4j.Slf4j; import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource; import javax.sql.DataSource; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @Slf4j public class HospDynamicDataSource extends AbstractRoutingDataSource { private final Map<Object, Object> targetDataSources = new ConcurrentHashMap<>(); // 存储所有数据源 @Override protected Object determineCurrentLookupKey() { return DataSourceContextHolder.getDataSourceKey(); // 根据上下文获取当前数据源的键 String key = DataSourceContextHolder.getDataSourceKey(); log.info("当前数据源 ->{}",key); return key; // 根据上下文获取当前数据源的键 } // 添加目标数据源 public void addTargetDataSource(String key, DataSource dataSource) { if (dataSource != null) { targetDataSources.put(key, dataSource); super.setTargetDataSources(new ConcurrentHashMap<>(targetDataSources)); // 更新目标数据源 super.afterPropertiesSet(); // 重新初始化数据源 } } // 允许外部访问所有目标数据源 @Override pom.xml
@@ -126,6 +126,18 @@ <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>${druid.version}</version> <exclusions> <exclusion> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid</artifactId> <version>${druid.version}</version> </dependency> <!-- 解析客户端操作系统、浏览器等 -->