Spring动态添加数据源(全自动)

news2024/11/27 0:26:05

一、使用场景

1、现在网上所有写的动态数据源,都是假动态数据,都是预先知道要连接几个数据库,但这不满足具体真正需要动态添加连接数据库的需求;

2、在很多业务场景下,如项目默认连一个主数据库,服务启动后,因业务不停的变更,需要动态连接其它数据库处理数据,关键点是其它数据库,在服务启动前是不知道连接地址的,所以其它数据库的地址是无法预先配置在application.yml文件中

二、因项目需求,需要真正动态连接其它库处理数据

1、做之前,百度网上搜,都是假动态数据源,为实现上面的真正动态添加数据,也花了几天时间才集成起,废话不多说

三、准备工作

1、准备三个数据,db_main,db_add01,db_add02,其中db_main为项目起动,默认连的主数据库,为了下面测试方便,我在三个数据库中创建了不同的三张表sys_company、sys_role、sys_user,以表示查询的数据不同,数据来源于不同的数据库,截图如下

application.yml中配置主数据库接信息

server:
  port: 8085
spring:
  application:
    name: mydata
  datasource:
    username: root
    password: 123456
    url: jdbc:mysql://192.168.137.202:3306/db_main?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=GMT%2B8
    druid:
      initialSize: 5
      minIdle: 5
      maxActive: 20
      maxWait: 60000
      #配置监控属性: 在druid-starter的: com.alibaba.druid.spring.boot.autoconfigure.stat包下进行的逻辑配置
      # WebStatFilter配置,
      stat-view-servlet:
        #配置DruidStatViewServlet的访问地址。后台监控页面的访问地址
        url-pattern: /druid/*
        #禁用HTML页面上的“重置”功能,会把所有监控的数据全部清空,一般不使用
        reset-enable: false
        #监控页面登录的用户名
        login-username: admin
        #监控页面登录的密码
        login-password: 123456
        #白名单
        allow:
        #黑名单
        deny:

 2、动态添加数据库核心代码

/**
     * 添加私有数据源
     * @param dbName 数据库名
     * @param url
     * @param username
     * @param password
     */
    public void addDataSource(String dbName,String url,String username,String password){
        if(!StringUtils.isEmpty(dbName)) {
            if (dataSourcesMap.get(dbName) == null) {
                DataSource dataSource = druidDataSource(url, username, password);
                dataSourcesMap.put(dbName, dataSource);
                super.setTargetDataSources(dataSourcesMap);
                super.afterPropertiesSet();
            } else {
                DruidDataSource dataSource = (DruidDataSource) dataSourcesMap.get(dbName);
                if (!dataSource.isEnable()) {
                    try {
                        dataSource.restart();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    }

    /**
     * 移出对应数据源
     * @param dbName
     */
    public void removeDataSource(String dbName){
        if(dataSourcesMap.get(dbName)!=null) {
            DruidDataSource dataSource= (DruidDataSource)dataSourcesMap.get(dbName);
            dataSourcesMap.remove(dbName);
            dataSource.close();
            super.afterPropertiesSet();
        }
    }

3、动态切换数据库

//线程本地环境
    private static final ThreadLocal<String> dataSources = new ThreadLocal<String>();
    //设置数据源,动态切换,就是调用这个setDataSource方法
    public static void setDataSource(String customerType) {
        dataSources.set(customerType);
    }
    //获取数据源
    public static String getDataSource() {
        return (String) dataSources.get();
    }
    //清除数据源
    public static void clearDataSource() {
        dataSources.remove();
    }

4、controller接口测试,代码如下

/**
     * 查询主库数据
     */
    @GetMapping (value="/findMain")
    public SysCompany findMain(@RequestParam(defaultValue = "C190829X5R")String id) {
        DataSourceHolder.setDataSource("db_main");
        SysCompany company = (SysCompany)dataService.findTById(SysCompany.class,id);
        return company;
    }

    /**
     * 查询db_add01号库数据
     * dbName 对应数据库名称
     */
    @GetMapping (value="/addDB")
    public String addDB(@RequestParam(defaultValue = "db_add01") String dbName, @RequestParam(defaultValue = "jdbc:mysql://192.168.137.202:3306/db_add01") String url,
                        @RequestParam(defaultValue = "root")String username, @RequestParam(defaultValue = "123456")String password) {
        dynamicDataSource.addDataSource(dbName,url,username,password);
        return "添加成功";
    }

    /**
     *
     * 查询db_add01号库数据
     * dbName 对应数据库名称
     */
    @GetMapping (value="/findDb01")
    public SysUser findDb01(@RequestParam(defaultValue = "db_add01")String dbName,@RequestParam(defaultValue = "5")String id) {
        DataSourceHolder.setDataSource(dbName);
        SysUser sysUser = (SysUser)dataService.findTById(SysUser.class,id);
        return sysUser;
    }

    /**
     * 查询db_add02号库数据
     * dbName 对应数据库名称
     */
    @GetMapping (value="/findDb02")
    public SysRole findDb02(@RequestParam(defaultValue = "db_add02")String dbName,@RequestParam(defaultValue = "1")String id) {
        DataSourceHolder.setDataSource(dbName);
        SysRole sysRole = (SysRole)dataService.findTById(SysRole.class,id);
        return sysRole;
    }

四、测试

1、查询主库数据,GET请求 http://localhost:8085/app/findMain?id=C190829X5R

 

 2、为了演示效果,我们在不添加db_add01库之前,查询一下db_add01库中的表sys_user,是要报错的 http://localhost:8085/app/findDb01?dbName=db_add01&id=5

 3、添加db_add01号库,后查询数据

添加库:http://localhost:8085/app/addDB?dbName=db_add02&url=jdbc:mysql://192.168.137.202:3306/db_add02&username=root&password=123456

 

 

上面db_add01添加之后,查询db_add01,数据可以顺利查询出来: 

http://localhost:8085/app/findDb01?dbName=db_add01&id=5

 五、总结

1、在db_add01添加之前,查询db_add01库中的表sys_user,服务报错,找不到对应的表

2、在通过接口添加db_add01数据库之后,可以正常查询出数据

3、如需要源代码,可下载 百度网盘 请输入提取码

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/471431.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

必知的Facebook广告兴趣定位技巧,更准确地找到目标受众

在Facebook广告投放中&#xff0c;兴趣定位是非常重要的一环。兴趣定位不仅可以帮助我们找到我们想要的目标受众&#xff0c;还可以帮助我们避免一些常见的坑。今天&#xff0c;就让我们一起来看看必知的Facebook广告兴趣定位技巧&#xff0c;更准确地找到目标受众。 1.不要只关…

北京/西安/杭州/深圳CDGA/CDGP数据治理认证班于2023年5月7日开班

DAMA认证为数据管理专业人士提供职业目标晋升规划&#xff0c;彰显了职业发展里程碑及发展阶梯定义&#xff0c;帮助数据管理从业人士获得企业数字化转型战略下的必备职业能力&#xff0c;促进开展工作实践应用及实际问题解决&#xff0c;形成企业所需的新数字经济下的核心职业…

蓝牙基础介绍

目录 一、概述&#xff08;Overview&#xff09; 二、框架结构&#xff08;Frame Structure&#xff09; 三、蓝牙协议&#xff08;Bluetooth Protocol&#xff09; 一、概述&#xff08;Overview&#xff09; 什么是蓝牙&#xff1f;就像你们大多数人想知道任何你从未听说过…

Redis-01-基础-redis简介安装、数据类型、常用命令、使用Spring Data Redis封装好的命令方法操作redis

文章目录 Redis基础课程内容1. 前言1.1 什么是Redis1.2 使用Redis能做什么 2. Redis入门2.1 Redis简介2.2 Redis下载与安装2.2.1 Redis下载2.2.2 Redis安装 2.3 Redis服务启动与停止2.4 Redis配置文件 3. Redis数据类型3.1 介绍3.2 Redis 5种常用数据类型 4. Redis常用命令4.1 …

Unity TextMeshPro文本存在背景框的问题研究

在使用TextMeshPro的时候遇到了字体黑底的问题&#xff0c;类似下图这样 当字体较大的时候表现正常&#xff0c;当缩小到一定程度就会出现黑底。这个情况让人第一时间就是怀疑SDF计算缩放的时候存在问题。在我们重新导出字体&#xff0c;调整图集字体大小以及Padding后&#xf…

基于GA遗传算法的列车交路优化MATLAB代码

资源地址&#xff1a; 基于GA遗传优化算法的列车交路方案优化matlab代码资源-CSDN文库 问题描述&#xff1a; 列车交路是指列车在规定的运行线路上往返运行的方式&#xff0c;规定了列车运行区段、折返车站以及按不同交路运行的列车对数. 对于既有线路&#xff0c;正在进行机…

【2023年五一数学建模竞赛B题】快递需求分析问题--完整思路和代码

1.问题背景与描述 赛题分析&#xff1a;这道题出的比较好&#xff0c;考察面较多&#xff0c;难度循环渐进&#xff0c;相对C题是比较有层次的一道题 2.解题思路分析 2.1 问题一的分析 请从收货量、发货量、快递数量增长/减少趋势、相关性等多角度考虑&#xff0c;建立数学模…

d3.js学习笔记②搭建服务器(含报错解决)

强烈建议自己搭建一个服务器&#xff0c;否则在后续往js里导入本地数据&#xff08;比如csv、json文件等&#xff09;的时候会报错。我用的是Apache服务器&#xff0c;下载、安装过程参考这篇文章&#xff1a;Apache安装配置 在浏览器输入http://localhost/或者http://127.0.0…

2023轻薄投影仪选哪款?极米Z6X Pro成年轻人租房首选投影

生活在哪里&#xff1f;大隐隐于市&#xff0c;小隐隐于出租屋。在那小小出租屋里&#xff0c;租房人开始选择自己打造一个“家”。一般情况下&#xff0c;在外租房的房间整体面积比较小&#xff0c;选择轻薄的投影仪是一个很好的选择。而国内知名投影品牌极米科技推出的这款轻…

WebLogic LinkRef 反序列化远程代码执行漏洞(CVE-2023-21931)

漏洞描述 Oracle WebLogic Server 是一款Java EE应用服务器。 受影响版本的WebLogic中WLNamingManager#getObjectInstance()存在JNDI查找逻辑&#xff0c;导致攻击者可以通过IIOP协议传入特定的对象触发反序列化逻辑&#xff0c;执行任意代码。 当传入boundObject 对象是 Li…

MySQL的数据库引擎介绍

1、什么是数据库引擎 数据库引擎就是操作数据库的一段程序或程序段&#xff0c;用于存储、处理和保护数据的核心服务。 利用数据库引擎可控制访问权限并快速处理事务&#xff0c;从而满足企业内大多数需要处理大量数据的应用程序的要求。数据库应用项目是通过数据库引擎与数据库…

干货好文 | 两地三中心到异地双活演变及关键技术探讨

两地三中心和异地多活都是分布式系统的关键技术&#xff0c;用于保证系统的高可用性和容错性。其中最关键的技术无疑是数据同步、同步防环和数据冲突解决。 异地容灾 & 两地三中心 两地三中心架构是一种分布式系统的架构模式&#xff0c;用于保证系统的高可用性和容错性。…

Numpy从入门到精通——节省内存|通用函数

这个专栏名为《Numpy从入门到精通》&#xff0c;顾名思义&#xff0c;是记录自己学习numpy的学习过程&#xff0c;也方便自己之后复盘&#xff01;为深度学习的进一步学习奠定基础&#xff01;希望能给大家带来帮助&#xff0c;爱睡觉的咋祝您生活愉快&#xff01; 这一篇介绍《…

适合学生党的蓝牙耳机品牌有哪些?学生性价比高的蓝牙耳机排行

近几年&#xff0c;蓝牙耳机凭借便捷的使用迅速成为人们外出常备的数码产品之一。现如今&#xff0c;市面上的蓝牙耳机越来越多&#xff0c;不同品牌&#xff0c;不同型号的蓝牙耳机数不胜数。那么&#xff0c;有没有适合学生党的蓝牙耳机品牌&#xff1f;针对这个问题&#xf…

试试这几个冷门但好用的软件吧

软件一&#xff1a;探记 探记是一款专注于个人记录每一条记录的工具&#xff0c;主要特点如下&#xff1a; 简单易用&#xff1a;探记的界面设计简洁明了&#xff0c;操作流程简单易用&#xff0c;用户可以快速、方便地添加记录。 多样化记录类型&#xff1a;探记支持多种记…

接口自动化测试面试、拿下10个题,你可以游刃有余

目录 1.请问你是如何做接口测试的&#xff1f; 2.接口测试如何设计测试用例&#xff1f; 3.接口测试执行中需要比对数据库吗&#xff1f; 4.接口测试质量评估标准是什么&#xff1f; 5.接口产生的垃圾数据如何清理 6.其他接口要先获取接口信息&#xff0c;如何让登录的接…

土木人职场受挫该如何破局?转行IT互联网貌似已成首选!

“大学毕业两年&#xff0c;一直在内耗。既不想继续做工程&#xff0c;又不知道出了工地&#xff0c;自己还能做什么&#xff1f;” 本人毕业于一类院校的建筑环境与能源应用工程专业&#xff0c;通俗的说就是土木工程。 进施工单位是大部分土木人的归宿&#xff0c;本科毕业生…

户外专家REI的EDI需求详解

REI是美国著名的户外用品零售商&#xff0c;成立于1938年&#xff0c;总部位于西雅图。REI以提供高品质户外用品和服务为主要目标&#xff0c;包括登山、露营、徒步旅行、滑雪、骑行等各种户外活动所需要的装备和用品。REI的供应商来自世界各地&#xff0c;包括美国本土和国际市…

2023年第二十届五一数学建模竞赛题目 C题详细思路

详细思路以及发布视频版&#xff0c;大家可以去观看&#xff0c;这里是对应的文字版&#xff0c;内容相差不多。 C题&#xff1a;“双碳”目标下低碳建筑研究 C题的问题设置其实是本次比赛最简单的一道&#xff0c;就是简单的综合评价预测模型。真正提升C题难度的其实是C题的…

〖ChatGPT实践指南 - 零基础扫盲篇⑧〗- OpenAI 的 模型(Model) 介绍

文章目录 ⭐ OpenAI 模型列表⭐ GPT 模型&#x1f31f; GPT-3 模型&#x1f31f; GPT-3.5 模型&#x1f31f; GPT-4 模型 ⭐ 特定功能的模型&#x1f31f; DALLE 模型&#x1f31f; Whisper模型&#x1f31f; Embeddings 模型&#x1f31f; Codex 模型&#x1f31f; Moderation…