动态数据源无需重启刷新
This commit is contained in:
parent
257db6a837
commit
e9f729ebc8
|
|
@ -0,0 +1,24 @@
|
||||||
|
package com.nu.modules.common;
|
||||||
|
|
||||||
|
import org.jeecg.modules.data.loader.DataSourceLoader;
|
||||||
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
|
import org.springframework.web.bind.annotation.PostMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RequestMapping;
|
||||||
|
import org.springframework.web.bind.annotation.RestController;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 系统工具
|
||||||
|
*/
|
||||||
|
@RestController
|
||||||
|
@RequestMapping("/api/sysUtils")
|
||||||
|
public class SysUtilsApi {
|
||||||
|
|
||||||
|
@Autowired
|
||||||
|
private DataSourceLoader dataSourceLoader;
|
||||||
|
|
||||||
|
@PostMapping("/refreshDS")
|
||||||
|
public String refresh() {
|
||||||
|
dataSourceLoader.refreshDataSources();
|
||||||
|
return "数据源已刷新";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -119,6 +119,7 @@ public class ShiroConfig {
|
||||||
filterChainDefinitionMap.put("/weixin/**", "anon"); //授权接口排除
|
filterChainDefinitionMap.put("/weixin/**", "anon"); //授权接口排除
|
||||||
filterChainDefinitionMap.put("/api/pad/loginApi/**", "anon"); //pad登录-信息获取接口
|
filterChainDefinitionMap.put("/api/pad/loginApi/**", "anon"); //pad登录-信息获取接口
|
||||||
filterChainDefinitionMap.put("/sys/common/open/static/**", "anon");//获取本地文件资源
|
filterChainDefinitionMap.put("/sys/common/open/static/**", "anon");//获取本地文件资源
|
||||||
|
filterChainDefinitionMap.put("/api/sysUtils/refreshDS", "anon");//刷新数据源
|
||||||
|
|
||||||
filterChainDefinitionMap.put("/sys/getLoginQrcode/**", "anon"); //登录二维码
|
filterChainDefinitionMap.put("/sys/getLoginQrcode/**", "anon"); //登录二维码
|
||||||
filterChainDefinitionMap.put("/sys/getQrcodeToken/**", "anon"); //监听扫码
|
filterChainDefinitionMap.put("/sys/getQrcodeToken/**", "anon"); //监听扫码
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ import org.springframework.stereotype.Service;
|
||||||
import javax.annotation.PostConstruct;
|
import javax.annotation.PostConstruct;
|
||||||
import javax.sql.DataSource;
|
import javax.sql.DataSource;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
@Service
|
@Service
|
||||||
|
|
@ -27,11 +28,50 @@ public class DataSourceLoader {
|
||||||
refreshDataSources();
|
refreshDataSources();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// public void refreshDataSources() {
|
||||||
|
// DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
|
||||||
|
// DataSource mainDataSource = ds.getDataSource("devops");
|
||||||
|
//
|
||||||
|
// // 从主数据源读取配置
|
||||||
|
// List<DataSourceEntity> configs = new JdbcTemplate(mainDataSource).query(
|
||||||
|
// "SELECT id, code, name, db_type, db_driver, db_url, db_name, db_username ,db_password ,sys_org_code FROM sys_data_source",
|
||||||
|
// (rs, rowNum) -> new DataSourceEntity(
|
||||||
|
// rs.getString("id"),
|
||||||
|
// rs.getString("code"),
|
||||||
|
// rs.getString("name"),
|
||||||
|
// rs.getString("db_type"),
|
||||||
|
// rs.getString("db_driver"),
|
||||||
|
// rs.getString("db_url"),
|
||||||
|
// rs.getString("db_name"),
|
||||||
|
// rs.getString("db_username"),
|
||||||
|
// rs.getString("db_password"),
|
||||||
|
// rs.getString("sys_org_code")
|
||||||
|
// )
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// // 创建并添加数据源
|
||||||
|
// configs.forEach(config -> {
|
||||||
|
// DataSourceProperty dataSourceProperty = new DataSourceProperty();
|
||||||
|
// dataSourceProperty.setUrl(config.getDbUrl());
|
||||||
|
// dataSourceProperty.setUsername(config.getDbUsername());
|
||||||
|
// String dbPassword = SecurityUtil.jiemi(config.getDbPassword());
|
||||||
|
// dataSourceProperty.setPassword(dbPassword);
|
||||||
|
// dataSourceProperty.setDriverClassName(config.getDbDriver());
|
||||||
|
// DataSource dynamicDataSource = dataSourceCreator.createDataSource(dataSourceProperty);
|
||||||
|
// ds.addDataSource(config.getCode(), dynamicDataSource);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
public void refreshDataSources() {
|
public void refreshDataSources() {
|
||||||
DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
|
DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
|
||||||
DataSource mainDataSource = ds.getDataSource("devops");
|
|
||||||
|
|
||||||
// 从主数据源读取配置
|
// 1. 从固定的主数据源(如 devops)读取最新的动态数据源配置
|
||||||
|
DataSource mainDataSource = ds.getDataSource("devops"); // 必须是静态配置的,不能被动态删除!
|
||||||
|
if (mainDataSource == null) {
|
||||||
|
log.error("无法获取主数据源 'devops',刷新动态数据源失败!");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
List<DataSourceEntity> configs = new JdbcTemplate(mainDataSource).query(
|
List<DataSourceEntity> configs = new JdbcTemplate(mainDataSource).query(
|
||||||
"SELECT id, code, name, db_type, db_driver, db_url, db_name, db_username ,db_password ,sys_org_code FROM sys_data_source",
|
"SELECT id, code, name, db_type, db_driver, db_url, db_name, db_username ,db_password ,sys_org_code FROM sys_data_source",
|
||||||
(rs, rowNum) -> new DataSourceEntity(
|
(rs, rowNum) -> new DataSourceEntity(
|
||||||
|
|
@ -48,17 +88,33 @@ public class DataSourceLoader {
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
// 创建并添加数据源
|
|
||||||
configs.forEach(config -> {
|
|
||||||
DataSourceProperty dataSourceProperty = new DataSourceProperty();
|
|
||||||
dataSourceProperty.setUrl(config.getDbUrl());
|
|
||||||
dataSourceProperty.setUsername(config.getDbUsername());
|
|
||||||
String dbPassword = SecurityUtil.jiemi(config.getDbPassword());
|
|
||||||
dataSourceProperty.setPassword(dbPassword);
|
|
||||||
dataSourceProperty.setDriverClassName(config.getDbDriver());
|
|
||||||
DataSource dynamicDataSource = dataSourceCreator.createDataSource(dataSourceProperty);
|
|
||||||
ds.addDataSource(config.getCode(), dynamicDataSource);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// 2. 新增或更新
|
||||||
|
for (DataSourceEntity config : configs) {
|
||||||
|
String code = config.getCode();
|
||||||
|
if (code == null || code.isEmpty()) {
|
||||||
|
log.warn("跳过无效数据源配置(code 为空): {}", config);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
DataSourceProperty prop = new DataSourceProperty();
|
||||||
|
prop.setUrl(config.getDbUrl());
|
||||||
|
prop.setUsername(config.getDbUsername());
|
||||||
|
prop.setPassword(SecurityUtil.jiemi(config.getDbPassword()));
|
||||||
|
prop.setDriverClassName(config.getDbDriver());
|
||||||
|
|
||||||
|
DataSource newDs = dataSourceCreator.createDataSource(prop);
|
||||||
|
ds.addDataSource(code, newDs); // 如果已存在,会先 close 旧的再替换(DynamicRoutingDataSource 内部逻辑)
|
||||||
|
log.info("已添加/更新动态数据源: {}", code);
|
||||||
|
} catch (Exception e) {
|
||||||
|
log.error("创建/更新数据源失败,code={}", code, e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info("动态数据源同步完成。当前动态数据源列表: {}",
|
||||||
|
ds.getDataSources().keySet().stream()
|
||||||
|
.filter(name -> !name.equals("master"))
|
||||||
|
.collect(Collectors.toList()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue