一、工具类
java
import com.baomidou.dynamic.datasource.DynamicRoutingDataSource;
import com.baomidou.dynamic.datasource.creator.DataSourceProperty;
import com.baomidou.dynamic.datasource.creator.DefaultDataSourceCreator;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.sql.DataSource;
import java.util.Set;
/**
* 动态数据源管理工具类
*/
@Slf4j
@Component
@RequiredArgsConstructor
public class DynamicDataSourceUtil {
private final DataSource dataSource;
private final DefaultDataSourceCreator dataSourceCreator;
/**
* 动态添加并注册数据源
*
* @param key 数据源别名
* @param url JDBC URL
* @param username 账号
* @param password 密码
* @param driverClassName 驱动
*/
public void addDataSource(String key, String url, String username, String password, String driverClassName) {
// 封装数据源配置属性
DataSourceProperty dto = new DataSourceProperty();
dto.setPoolName(key);
dto.setUrl(url);
dto.setUsername(username);
dto.setPassword(password);
dto.setDriverClassName(driverClassName);
// 使用 Creator 创建数据源
DataSource newDataSource = dataSourceCreator.createDataSource(dto);
// 强制转型并添加至动态管理器
DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
ds.addDataSource(key, newDataSource);
log.info("动态数据源 [{}] 已成功添加。", key);
}
/**
* 移除数据源
* 移除时会自动调用 close() 方法释放连接池资源
*/
public void removeDataSource(String key) {
DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
ds.removeDataSource(key);
log.info("动态数据源 [{}] 已成功移除。", key);
}
/**
* 获取当前所有激活的数据源名称
*/
public Set<String> getCurrentDataSources() {
DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
return ds.getDataSources().keySet();
}
/**
* 判断数据源是否存在
*/
public boolean exists(String key) {
DynamicRoutingDataSource ds = (DynamicRoutingDataSource) dataSource;
return ds.getDataSources().containsKey(key);
}
/**
* 测试数据库连通性
*
* @param url JDBC URL
* @param username 账号
* @param password 密码
* @return boolean 是否连接成功
*/
public boolean testConnection(String url, String username, String password, String driverClassName) {
Connection conn = null;
try {
// 加载驱动
Class.forName(driverClassName);
// 尝试获取连接,设置超时时间为 5 秒,防止长时间卡住
DriverManager.setLoginTimeout(5);
conn = DriverManager.getConnection(url, username, password);
return conn != null;
} catch (ClassNotFoundException e) {
log.error("未找到数据库驱动: {}", e.getMessage());
return false;
} catch (SQLException e) {
log.warn("数据库连接测试失败: URL={}, 原因={}", url, e.getMessage());
return false;
} finally {
// 手动释放连接
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
log.error("关闭测试连接异常", e);
}
}
}
}
}
二、 业务中切换数据源
java
// 包路径
import com.baomidou.dynamic.datasource.toolkit.DynamicDataSourceContextHolder;
// 切换数据源
DynamicDataSourceContextHolder.push(key);
// 使用此数据源
try{
// 业务逻辑
} finally {
DynamicDataSourceContextHolder.poll();
}
使用场景,需要在数据库中管理数据源地址并应用到实际业务逻辑中的