mysql drivermanager_jdbc详解:2、DriverManager管理多个数据库驱动

2023-10-27

先上代码

static String driverName = "com.mysql.jdbc.Driver";

static String url = "jdbc:mysql://127.0.0.1:3306/mysql";

static String username = "root";

static String password = "";

@Test

public void getConnection1() {

DriverManager.setLogWriter(new PrintWriter(System.out));

try {

// 1、加载驱动,不加载驱动依然正常可以连接

// Class.forName(driverName);

// 2、获取connection

Connection conn = DriverManager.getConnection(url, username, password);

// 3、依然可以获取链接

System.out.println(conn);

// 查看已经加载的driver

Enumeration drivers = DriverManager.getDrivers();

System.out.println("------加载的diver--------");

while(drivers.hasMoreElements()) {

System.out.println(drivers.nextElement().getClass().getName());

}

} catch (Exception e) {

e.printStackTrace();

}

}

上面代码,没有手动加载驱动,但是依然可以获取连接

控制台输出信息

DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mysql")

trying com.mysql.jdbc.Driver

getConnection returning com.mysql.jdbc.Driver

com.mysql.jdbc.JDBC4Connection@72d8c235

------加载的diver--------

com.mysql.jdbc.Driver

com.mysql.fabric.jdbc.FabricMySQLDriver

从输出可以看到,DriverManager自动加载了com.mysql.jdbc.Driver和com.mysql.fabric.jdbc.FabricMySQLDriver这两个驱动,这也可以说明DriverManager可以管理多个驱动。

下面我们来看一下DriverManager的源码:

public class DriverManager {

static {

// 类加载时候就进行了加载数据库操作

loadInitialDrivers();

println("JDBC DriverManager initialized");

}

//其他代码省略

private static void loadInitialDrivers() {

String drivers;

try {

// AccessController.doPrivileged这个方法可以看做临时扩大该类的权限

// 读取系统jdbc.drivers的配置

drivers = AccessController.doPrivileged(new PrivilegedAction() {

public String run() {

return System.getProperty("jdbc.drivers");

}

});

} catch (Exception ex) {

drivers = null;

}

AccessController.doPrivileged(new PrivilegedAction() {

public Void run() {

// 扫描 java.sql.Driver的实现类,并加载

// 加载就按照前一篇文章一样进行驱动注册

ServiceLoader loadedDrivers = ServiceLoader.load(Driver.class);

Iterator driversIterator = loadedDrivers.iterator();

try{

while(driversIterator.hasNext()) {

driversIterator.next();

}

} catch(Throwable t) {

// Do nothing

}

return null;

}

});

println("DriverManager.initialize: jdbc.drivers = " + drivers);

if (drivers == null || drivers.equals("")) {

return;

}

// 加载System中的jdbc.drivers参数指定的驱动,可以是多个驱动,以“:”分割

String[] driversList = drivers.split(":");

println("number of Drivers:" + driversList.length);

for (String aDriver : driversList) {

try {

println("DriverManager.Initialize: loading " + aDriver);

Class.forName(aDriver, true,

ClassLoader.getSystemClassLoader());

} catch (Exception ex) {

println("DriverManager.Initialize: load failed: " + ex);

}

}

}

}

加载mysql和oracle驱动,分别连接到mysql和oracle数据库

static String MYSQL_DRIVERNAME = "com.mysql.jdbc.Driver";

static String MYSQL_URL = "jdbc:mysql://127.0.0.1:3306/mysql";

static String MYSQL_USERNAME = "root";

static String MYSQL_PASSWORD = "";

static String ORALE_DRIVERNAME = "oracle.jdbc.driver.OracleDriver";

static String ORALE_URL = "jdbc:oracle:thin:@10.211.55.6:1521:ORCL";

static String ORALE_USERNAME = "system";

static String ORALE_PASSWORD = "orcl";

@Test

public void getConnection1() {

// 输出DriverManager 的日志信息到控制台

DriverManager.setLogWriter(new PrintWriter(System.out));

// 获取mysql连接

try {

// 1、加载驱动

Class.forName(MYSQL_DRIVERNAME);

// 2、获取connection

Connection conn = DriverManager.getConnection(MYSQL_URL, MYSQL_USERNAME, MYSQL_PASSWORD);

System.out.println(conn);

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

}

// 获取oracle连接

try {

// 1、加载驱动

Class.forName(ORALE_DRIVERNAME);

// 2、获取connection

Connection conn = DriverManager.getConnection(ORALE_URL, ORALE_USERNAME, ORALE_PASSWORD);

System.out.println(conn);

} catch (ClassNotFoundException e) {

e.printStackTrace();

} catch (SQLException e) {

e.printStackTrace();

}

}

执行,控制台输出

DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mysql")

trying com.mysql.jdbc.Driver

getConnection returning com.mysql.jdbc.Driver

com.mysql.jdbc.JDBC4Connection@22b3428e

DriverManager.getConnection("jdbc:oracle:thin:@10.211.55.6:1521:ORCL")

trying com.mysql.jdbc.Driver

trying com.mysql.fabric.jdbc.FabricMySQLDriver

trying oracle.jdbc.OracleDriver

getConnection returning oracle.jdbc.OracleDriver

oracle.jdbc.driver.T4CConnection@28d51032

上述代码DriverManager同时连接oracle和mysql,换句话说,DriverManager同时管理着oracle和mysql两个驱动。那我们会产生疑问DriverManager到底是如果多个管理驱动的,怎么样根据我们的连接配置信息(url,密码...)获取到对应的连接?

驱动的管理或者说记录是封装成DriverInfo后放到DriverInfoCopyOnWriteArrayList,可以看做是一个线程安全的ArrayList。

private final static CopyOnWriteArrayList registeredDrivers = new CopyOnWriteArrayList();

当我们要获取连接的时候,再遍历registeredDrivers这个列表,然后使用列表中的驱动尝试连接,当获取到连接以后就停止遍历,然后返回connection

DriverManager的核心连接代码

private static Connection getConnection(

String url, java.util.Properties info, Class> caller) throws SQLException {

// 省略。。。

println("DriverManager.getConnection(\"" + url + "\")");

SQLException reason = null;

// 遍历驱动注册列表

for(DriverInfo aDriver : registeredDrivers) {

// 判断是否能使用该驱动

if(isDriverAllowed(aDriver.driver, callerCL)) {

try {

println(" trying " + aDriver.driver.getClass().getName());

// 尝试连接

/**

* 其实java.sql.Driver接口定义了一个方法判断驱动能不能接受url的连接,

* boolean acceptsURL(String url) throws SQLException;

* 这里其实先使下面代码进行判断

* if (!aDriver.driver.acceptsURL(url)) {

* continue;

* }

* 但是没有使用上面代码进行判断,我猜可能的原因是:

* 1、java官方并不要求实现acceptsURL()方法,我们平常

* 使用也很早用到这个方法。

* 2、存在一种这样的情况:某个数据库厂商协议进行升级

* 了,但是为了兼容旧的协议还是允许连接,

* acceptsURL(旧协议的url)方法,返回false,

* 起到一个提示的作用。

*/

Connection con = aDriver.driver.connect(url, info);

if (con != null) {

// Success!

println("getConnection returning " + aDriver.driver.getClass().getName());

// 没有报异常并且 connection 不为空,则返回connection

return (con);

}

} catch (SQLException ex) {

if (reason == null) {

reason = ex;

}

}

} else {

println(" skipping: " + aDriver.getClass().getName());

}

}

// if we got here nobody could connect.

if (reason != null) {

println("getConnection failed: " + reason);

throw reason;

}

println("getConnection: no suitable driver found for "+ url);

throw new SQLException("No suitable driver found for "+ url, "08001");

}

}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

mysql drivermanager_jdbc详解:2、DriverManager管理多个数据库驱动 的相关文章

  • Ubuntu安装软件时Could not get lock /var/lib/dpkg/lock - open (11: Resource temporarily unavailable)的解决方案

    Ubuntu 19 04 在安装wireshark的时候 sudo apt get install wireshark后遇到报错如下 E Could not get lock var lib dpkg lock open 11 Resour
  • 运维基础知识

    一 简述运维流程 1 接手平台 管理资产 增删 设置平台对资产是扫描策略 2 每天按照规定的巡检周期对资产进行巡检 巡检过程中检测资产的目前状态做记录 查看是否有新增告警事件 将发现的新增告警事件按照规定输出详细的事件工单 工单内要求详细描
  • Error processing condition on org.springframework.cloud.commons.httpclient.HttpClientConfiguration

    背景 创建springboot项目后 导入nacos 配置中心和注册中心依赖后报错 springboot启动类无法正常启动 控制台异常如题 报错源码 java lang IllegalStateException Error process
  • Springboot数据库连接池报错的解决办法

    Springboot数据库连接池报错的解决办法 这个异常通常在Linux服务器上会发生 原因是Linux系统会主动断开一个长时间没有通信的连接 那么我们的问题就是 数据库连接池长时间处于间歇状态 导致Linux系统将其断开了 然后抛出了这个
  • 关于解决win10的 tencent qqmail plugin 卸载不了的问题

    问题出现场景 我也是偶然一次在搜索我电脑里面下载的程序时 发现有个叫做tencent qqmail plugin的程序怎么也删除不掉 经过的我不断的尝试 欸 我终于找到解决方法了 问题描述 我之前使用的方法的是在 设置 应用 应用程序 中卸
  • 在VMware里克隆出来的CentOSLinux。。 ifconfig...没有看到eth0.。然后重启网卡又报下面错误。

    原文地址 http www 51testing com html 90 360490 846295 html 故障现象 service network restart Shutting down loopback insterface OK
  • 流程图中的虚线含义_流程图图形符号标准含义简介

    流程图是我们工作中经常会用到的一种工具 形象直观 便于理解 直观地描述一个工作过程的具体步骤 流程图对准确了解事情是如何进行的 以及决定应如何改进过程极有帮助 这一方法可以用于整个企业 以便直观地跟踪和图解企业的运作方式 流程图中有很多图形
  • 数据挖掘初探(skleran)

    1 使用sklearn进行数据挖掘 1 1 数据挖掘的步骤 数据挖掘通常包括数据采集 数据分析 特征工程 训练模型 模型评估等步骤 我们使用sklearn进行虚线框内的工作 sklearn也可以进行文本特征提取 通过分析sklearn源码
  • RT-Thread记录(十一、I/O 设备模型之UART设备 — 源码解析)

    深入理解 RT Thread I O 设备模型 分析 UART设备源码 目录 前言 一 初识 UART 操作函数 应用程序 二 UART 的初始化 2 1 UART 设备初始化位置 2 2 UART 设备初始化函数分析 stm32 uart
  • 华为IP的考试费要好几千,想问一下这个证书的含金量怎么样?

    虽然华为认证HCIP考试只考笔试 题库稳 运气好的话刷题库就有可能会过 但是其实学的时候还是好好学的 要不然只为了考试而去背题 但是实际操作能力不行的话一样会被企业拒绝的 最重要的还是掌握华为认证HCIP的技能 证书只是找工作的一个敲门砖
  • 服务器系统这么做,服务器怎么做系统

    服务器怎么做系统 内容精选 换一换 无法直接从云备份控制台查看备份中的数据 您可以通过以下几种方式进行查看 云服务器备份使用云服务器备份创建镜像后 再使用镜像创建云服务器 登录云服务器 查看服务器中的数据 云硬盘备份使用云硬盘备份创建新的云
  • 算法题:完全二叉树的权值

    问题描述 给定一棵包含 N 个节点的完全二叉树 树上每个节点都有一个权值 按从 上到下 从左到右的顺序依次是 A1 A2 AN 如下图所示 现在要把相同深度的节点的权值加在一起 他想知道哪个深度的节点 权值之和最大 如果有多个深度的权值和同
  • 代理模式,以及Java的动态代理

    定义 为其他对象提供一种代理以控制对这个对象的访问 可以提供额外不同的操作 UML类图 Subject类 定义了RealSubject和Proxy的共用接口 这样就在任何使用RealSubject的地方都可以使用Proxy RealSubj
  • UNIX环境高级编程 学习笔记 第十八章 终端I/O

    20世纪70年代后期 系统 UNIX System III 发展出一套不同于V7 Version 7 Unix 的终端IO例程 使得UNIX终端IO处理分立为两种不同风格 一种是系统 风格 它延续到了System V 另一种是V7风格 它成
  • 暴力破解Windows、Linux登录密码

    Windows密码破解 使用hydra离线破解windows密码 使用getpass内存提取windows用户密码 使用quarkpwdump导出windows用户密码hash值 Linux密码破解 使用hydra离线破解linux密码 将
  • idea启动java项目卡住问题

    当遇到 Method breakpoints may dramatically slow down debugging时 这时有可能可以进行下面步骤解决 Ctrl Shift F8 打开Breakpoints面板 然后可以测试是否可行
  • 记录好项目D21

    记录好项目 你好呀 这里是我专门记录一下从某些地方收集起来的项目 对项目修改 进行添砖加瓦 变成自己的闪亮项目 修修补补也可以成为毕设哦 本次的项目是个基于Springboot的教务管理系统 学生管理系统 课表查询系统 一 系统介绍 本项目
  • 使用EventEmitter构建基础的生命周期模型

    使用EventEmitter构建基础的生命周期模型 比如onCreate onUpdate onDestroy 分别在每个阶段console log一条消息 比如说 我们构建一个便签管理的EventEmitter 在onCreate时初始化
  • 献给面试学生 关键字const是什么意思 ESP(译者:Embedded Systems Programming) --Dan Saks概括了const的所有用法

    关键字const是什么含意 答 我只要一听到被面试者说 const意味着常数 我就知道我正在和一个业余者打交道 去年Dan Saks已经在他的文章里完全概括了const的所有用法 因此ESP 译者 Embedded Systems Prog

随机推荐

  • 商品期货的模拟盘能打印交易记录吗(商品期货的模拟盘能打印交易记录吗为什么)

    商品期货模拟盘可以打印交易记录吗 仿真盘没有实际测试过 大家可以自己试试 股指期货模拟交易和股指期货模拟交易有什么区别 您好 开展模拟交易的目的是为了深化对股指期货合约 规则和制度的检验 开展投资者教育活动 在模拟的交易过程中 交易过程 结
  • 【4-3】多彩的声音

    设计和实现一 个Soundable发声接口 该接口具有发声功能 同时还能调节声音大小 Soundable接口的这些功能将由有3种声音设备来实现 他们分别是收音机Radio 随身听Walkman 手机MobilePhone 最后还需设计 个应
  • mac查看电脑ip(在终端输入命令)

    在终端输入命令 ipconfig getifaddr en0
  • 科普:你该认识的四种常见开源许可证

    为什么80 的码农都做不了架构师 gt gt gt 开源早已成为很多科技企业关注的焦点 我们也常会发现部分开源技术后面标注了某种协议 这意味着这些开源代码被框上了某种束缚 或者说这些代码将必须遵循这些规则 否则可能会触及法律 总的来看 如今
  • 【因果推断与机器学习】Causal Inference: Chapter_3

    Identification Introduction 在介绍这节的补充内容呢 我想先引进一个著名的 辛普森悖论 辛普森医生发现了一种新药 这种新药可以降低心脏病发作的风险 于是他开始查找历史的实验数据 他注意到 如果男性患者服用了这种药
  • P1102 A-B 数对

    include
  • 图解python吴灿铭网盘_正版 图解算法 使用Python 吴灿铭 数据结构程序调试方法技巧书数组堆栈链表队列算法书Pytho...

    第1章进入算法的世界1 1 1生活中到处都是算法2 1 1 1算法的定义3 1 1 2算法的条件4 1 1 3时间复杂度O f n 6 1 2常见算法简介7 1 2 1分治法8 1 2 2递归法9 第1章进入算法的世界1 1 1生活中到处都
  • vue后台管理系统(通用模板)

    后台管理通用框架 源码 GitHub 亲测有效 预览地址 目前 包含 动态侧边导航栏渲染 面包屑 通知 主题 富文本等 1 登陆 2 工作台 3 通知 4 主题 5 发邮件 6 通知详情 目前可实现Excel表格下载 请见MarkDown文
  • HoloLens MRTK2.7 Unity2020 URP

    先提供工程下载链接 链接 https pan baidu com s 11LUGRzaTBxWOjUFwjZBKLQ 提取码 8xy6 优点 XR Plugin已经融合了MR AR VR 工程不用修改可以打包不同平台 可以使用ShaderG
  • arm linux ntfs_Linux驱动02

    一 启动过程 上电 gt uboot gt 加载linux内核 gt 挂载根文件系统 gt 执行应用程序 emmm 接下来会对uboot linux内核 跟文件系统分析 二 uboot 1 什么是uboot uboot其实就是一个通用的引导
  • Python打开图像始终提示错误error:(-215) size.width>0 && size.height>0

    用Python打开图像始终提示错误 cv2 error C projects opencv python opencv modules highgui src window cpp 331 error 215 size width gt 0
  • 深度学习之CNN卷积神经网络

    详解卷积神经网络 CNN 卷积神经网络 Convolutional Neural Network CNN 是一种前馈神经网络 它的人工神经元可以响应一部分覆盖范围内的周围单元 对于大型图像处理有出色表现 概揽 卷积神经网络 Convolut
  • DNS over HTTPS来阻止DNS污染

    DNS 域名系统 的主要功能是将域名解析成IP地址 域名的解析工作由DNS服务器完成 从安全角度来看 域名解析的请求传输时通常不进行任何加密 这导致第三方能够很容易拦截用户的DNS 将用户的请求跳转到另一个地址 常见的攻击方法有DNS劫持和
  • 9.多重循环结构和程序调试

    2022 9 3 记录学习java的第九天 今天主要学习了多种循环的嵌套使用和程序调试 1 多重循环 使用方法 1 相同循环可以互相嵌套使用 2 各循环之间可以互相嵌套使用 3 外循环变量改变一次 内循环变量要从头到尾变化一遍 即 内循环是
  • 单链表算法实现, 查找, 删除, 销毁

    从链表的指定位置读取参数 从链表中查找第i个元素 用e来保存查找元素的数据 指定位置读取参数 list 头节点 i 要读取的位置 e 保存读取的元素 bool Link GetElem LinkList list int i int e i
  • 数组的indexOf 方法

    1 数组的indexOf 方法 String 类型的使用 let str orange str indexOf o 0 字符串中出现字母 o 的位置 str indexOf n 3 字符串中出现字母 n 的位置 str indexOf c
  • vue封装公共组件库并发布到npm库详细教程

    vue组件封装的原理 利用vue框架提供的api Vue use plugin 我们需要把封装好组件的项目打包成vue库 并提供install方法 然后发布到npm中 Vue use plugin 的时候会自动执行插件中的install方法
  • STM32CubeMX驱动ADS1118模块

    文章目录 1 前言 2 ADS1118模块简介 3 移植源码到工程 4 驱动源码中函数介绍 4 1 us延时函数 4 2 写入和读取ADS1118配置寄存器 4 3 初始化ADS1118 4 4 测量电压函数 5 实验 5 1 单通道采样
  • 2022年软件测试面试题大全【含答案】

    一 面试基础题 简述测试流程 1 阅读相关技术文档 如产品PRD UI设计 产品流程图等 2 参加需求评审会议 3 根据最终确定的需求文档编写测试计划 4 编写测试用例 等价类划分法 边界值分析法等 5 用例评审 主要参与人员 开发 测试
  • mysql drivermanager_jdbc详解:2、DriverManager管理多个数据库驱动

    先上代码 static String driverName com mysql jdbc Driver static String url jdbc mysql 127 0 0 1 3306 mysql static String user