Java使用Mybatis-Plus封装动态数据源工具类

一、工具类

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();
}

使用场景,需要在数据库中管理数据源地址并应用到实际业务逻辑中的

相关推荐
小马爱打代码12 小时前
Java 并发 Bug 深度分析与实战
java
matrixmind812 小时前
HTTPX:Python 下一代 HTTP 客户端
python·其他·http·httpx
怪兽学LLM12 小时前
LeetCode 21 合并两个有序链表:彻底理解虚拟头节点(Dummy)套路
python·leetcode·链表
XLYcmy12 小时前
一个基于 Python 的轻量级 LLM(大语言模型)API 客户端程序:从API交互到LLM应用架构
服务器·python·ai·llm·prompt·agent·token
程序员佳佳12 小时前
四个月长期实测:自建 Milvus、FAISS、原生向量 API 和向量引擎中转方案,到底怎么选?
人工智能·windows·python·gpt·milvus·faiss
shimly12345612 小时前
python3 venv 是啥?
python
极客先躯12 小时前
高级java每日一道面试题-2026年02月09日-实战篇[Docker]-Docker 容器有哪些安全风险?如何缓解?
java·运维·网络·安全·docker·容器
aqi0012 小时前
15天学会AI应用开发(六)使用离线大模型对文本生成摘要
人工智能·python·ai编程
_Aaron___12 小时前
MyBatis 动态排序别乱用 ${}:ORDER BY 的安全写法
java·spring·mybatis
摇滚侠12 小时前
SpringMVC 入门到实战 HttpMessageConverter 65-74
java·后端·spring·intellij-idea