解读MySQL驱动加载逻辑

我们很早之前就知道最基础的JDBC编写,先执行Class.forName方法,加载MySQL驱动。但是为什么加载过驱动后,后续的接口层的调用就会自动切换到MySQL的相关代码去执行呢?(作者:高元)

常见jdbc编写

Connection connection = null;

PreparedStatement ps = null;

ResultSet rs = null;

try {

Class.forName("com.mysql.jdbc.Driver");

connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/gdjt_db","root","root");

ps = connection.prepareStatement("select * from sys_user where id = ? ");

ps.setString(1, "1");

rs = ps.executeQuery();

while (rs.next()){

System.out.println(rs.getString("name"));

}

}catch (Exception e){

e.printStackTrace();

}finally {

try {

if(rs != null)rs.close();

}catch (Exception e){}

try {

if(ps != null)ps.close();

}catch (Exception e){}

try {

if(connection != null)connection.close();

}catch (Exception e){}

}

当然,我们这里使用MySQL来演示,所以需要导入相关依赖

mysql

mysql-connector-java

5.1.44

以上是最简单的JDBC实现,下面我们主要查看Class.forName("com.mysql.jdbc.Driver");具体的执行逻辑。

查看第一步具体做了什么?

Class.forName("com.mysql.jdbc.Driver");

1、我们先看Class.forName

@CallerSensitive

public static Class> forName(String className) throws ClassNotFoundException {

/** 获取调用者Class */

Class> caller = Reflection.getCallerClass();

/**

* 1、获取调用者的类加载器

* 2、执行类加载

* 3、执行初始化方法(initialize = true)

*/

return forName0(className, true, ClassLoader.getClassLoader(caller), caller);

}

具体内容见代码中的注解,可以发现,Class.forName主要就是类加载,加载了类com.mysql.jdbc.Driver

2、接着看mysql的Driver源码实现

/**

* java.sql.Driver 是jdk封装的驱动接口

*/

public class Driver extends NonRegisteringDriver implements java.sql.Driver {

public Driver() throws SQLException {

}

/** 上一步骤类加载器加载类时,执行了初始化方法,就是执行这里的static中的代码 */

static {

try {

/** 将当前mysql的Driver注册到DriverManager中 */

DriverManager.registerDriver(new Driver());

} catch (SQLException var1) {

throw new RuntimeException("Can't register driver!");

}

}

}

具体注册代码如下:

public static synchronized void registerDriver(java.sql.Driver driver, DriverAction da) throws SQLException {

if(driver != null) {

// 将mysql的driver封装成DriverInfo对象,并传入registeredDrivers链表中。

registeredDrivers.addIfAbsent(new DriverInfo(driver, da));

} else {

throw new NullPointerException();

}

}

其中 registeredDrivers 是全局的静态变量

private final static CopyOnWriteArrayList registeredDrivers = new CopyOnWriteArrayList<>();

这样,无论在哪里,都可以通过registeredDrivers来获取当前的驱动。

3、继续看Connection如何获取到对应的连接的

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

我们进入getConnection查看,代码稍微长点,不过没关系,我们只要看如下一行代码即可

private static Connection getConnection(String url, java.util.Properties info, Class> caller) throws SQLException {

...

// 看到了熟悉的身影 registeredDrivers

for(DriverInfo aDriver : registeredDrivers) {

...

// 从registeredDrivers获取之前存入的mysql对应的Driver

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

...

}

...

}

接着执行 driver.connect( ) 方法,之前我们看过 Driver 的源码

Driver extends NonRegisteringDriver implements java.sql.Driver

所以 driver.connect 的方法,不是在 Driver 中就是在 NonRegisteringDriver 中。 结果我们在 NonRegisteringDriver 中如愿以偿的找到了connect方法(118行左右)

public Connection connect(String url, Properties info) throws SQLException {

...

// 重要代码在这里,获取具体的连接实例

com.mysql.jdbc.Connection newConn = ConnectionImpl.getInstance(this.host(props), this.port(props), props, this.database(props), url);

return newConn;

...

}

接下来的步骤就不一一演示了。

总结

通过类加载器加载Driver并初始化,将Driver添加到DriverManager的registeredDrivers中;

通过registeredDrivers获取到Driver;

调用Driver的connect方法,获取Mysql中的MySQLConnection;

博客

开源中国博客地址

个人博客地址

欢迎关注我的个人微信订阅号:(据说这个头像程序猿专用)

mysql驱动如何编写_解读MySQL驱动加载逻辑相关推荐

  1. mysql修复损坏表_在MySQL中,如何修复损坏的表

    本指南旨在作为故障排除资源和诊断MySQL设置的起点. 有时,MySQL表损坏,这意味着发生了错误,并且其中的数据无法读取. 损坏表的一些常见原因是:MySQL服务器在写数据的时候停止.外部程序同时修 ...

  2. 解决研华数据采集板卡驱动包Xnavi在Win7系统下加载界面卡死问题

    问题:Xnavi驱动包在Win7系统下运行,无法进入驱动安装界面,一直停滞在加载界面. 处理过程与结果: 系统缺少一些补丁,需要更新系统或者安装以下补丁(Windows6.1-KB2921916)(W ...

  3. 关于使用scrapy框架编写爬虫以及Ajax动态加载问题、反爬问题解决方案

    关于使用scrapy框架编写爬虫以及Ajax动态加载问题.反爬问题解决方案 参考文章: (1)关于使用scrapy框架编写爬虫以及Ajax动态加载问题.反爬问题解决方案 (2)https://www. ...

  4. mysql驱动为什么自动加载_为什么JDBC中加载驱动要使用反射?

    原文链接:https://www.cnblogs.com/homejim/p/8076481.html 在JDBC详解系列(一)之流程中,我将数据库的连接分解成了六个步骤. JDBC流程: 第一步:加 ...

  5. mysql 查看slave状态_解读show slave status 命令判断MySQL复制同步状态

    解读show slave status 命令判断MySQL复制同步状态 1. show slave status命令可以显示主从同步的状态 MySQL> show slave status \G ...

  6. mysql数据库建仓范式_存mysql个数

    MySQL学习笔记之数据类型详解 注:以下内容针对MySQL5.0及以上版本 MySQL的数据类型非常多,选择正确的数据类型对于获得高性能至关重要,本文是我结合网上看到的一些blog加上<高性能 ...

  7. mysql 更改数据库编码_更改MySQL数据库的编码为utf8mb4

    utf-8编码可能2个字节.3个字节.4个字节的字符,但是MySQL的utf8编码只支持3字节的数据,而移动端的表情数据是4个字节的字符.如果直接往采用utf-8编码的数据库中插入表情数据,Java程 ...

  8. mysql 子查询概念_聊聊MySQL的子查询

    1. 背景 在之前介绍MySQL执行计划的博文中已经谈及了一些关于子查询相关的执行计划与优化.本文将重点介绍MySQL中与子查询相关的内容,设计子查询优化策略,包含半连接子查询的优化与非半连接子查询的 ...

  9. mysql运维机制_《MySQL运维内参》节选 | InnoDB日志管理机制(一)

    引 子 InnoDB 存储引擎是支持事务ACID特性的,它是以二十多年前IBM的一篇著名文章<ARIES:A Transaction Recovery Method Supporting Fin ...

最新文章

  1. Express结合Webpack的全栈自动刷新
  2. 路由器与计算机IP配置,路由器设置之前 如何给电脑设置IP地址
  3. [Usaco2007 Oct] Super Paintball超级弹珠
  4. 72年属鼠48岁有一灾2020_李半仙推算:1972年虚岁48岁属鼠人,2020年干什么最能发财??...
  5. 云服务器选ssd还是hdd_SSD和普通硬盘对比?SSD到底好不好?看超变态测试
  6. 将字符转换成带有圆圈的字符
  7. ppt修复无法读取_CVE20201938 Tomcat 文件读取/包含漏洞复现
  8. java+junit百科_JUnit介绍
  9. paypal支付交易数据
  10. 用css和js分别实现三级导航菜单
  11. 机械制图比例GB/T14690-93
  12. 21世纪最牛逼思想家的心路历程小结———哲学、宿命论
  13. 基于arduino的oled显示屏的使用
  14. 基站定位查询api使用接口
  15. 网易视频云首推多路互动直播,首批测试邀请火爆来袭
  16. 大军师司马懿之军师联盟
  17. 旺店通·企业奇门与金蝶云星空对接集成查询采购入库单连通采购入库新增(采购入库单 all)
  18. 那些年UNIX教我们的事
  19. 机器学习基础(五):计算学习理论(PAC学习、有限假设空间、VC维、Rademacher复杂度、稳定性)
  20. 灵魂之问:机器人编程学习的是什么?/机器人课与科学课/机器人课和编程课/乐高机器人学的是什么?

热门文章

  1. 如何在短期快速学好英文
  2. Unity可用 运行时语音合成(文本转语音)插件 RT-Voice PRO
  3. 免费域名注册的一些知识以及域名解析相关知识
  4. 音频格式简析解惑之二——无损压缩格式
  5. Pepper初级教程:第三章 Choregraphe用法
  6. php手术会导致,PHPV处理结果
  7. html引入kendo日期控件,kendo ui 日期插件:kendoDatePicker详解
  8. 注册域名,搭建自己的网站
  9. Renewed and collected my Singapore passport
  10. 在DOS环境下win7系统与win10系统的编程、链接及运行步骤(非常适合第一次学习DOS的小萌新入手)