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

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

相关推荐
期待のcode17 小时前
Java虚拟机类加载机制
java·开发语言
Learner17 小时前
Python运算符
开发语言·python
短剑重铸之日17 小时前
《SpringBoot4.0初识》第四篇:原生镜像
java·原生镜像·springboot4.0
程序员欣宸17 小时前
LangChain4j实战之十二:结构化输出之三,json模式
java·人工智能·ai·json·langchain4j
一晌小贪欢17 小时前
Python 精确计算:告别浮点数陷阱,decimal 模块实战指南
开发语言·python·python入门·python3·python小数·python浮点数
空城雀17 小时前
python精通连续剧第一集:简单计算器
服务器·前端·python
天若有情67317 小时前
打破思维定式!C++参数设计新范式:让结构体替代传统参数列表
java·开发语言·c++
斯特凡今天也很帅17 小时前
python测试SFTP连通性
开发语言·python·ftp