我们都知道JDBC的代码怎么写,比如以MySQL JDBC为例

 //注册JDBC驱动
Class.forName("com.mysql.jdbc.Driver"); //然后就可以拿到JDB的连接
DriverManager.getConnection("jdbc:mysql://localhost/quickstart", "root", "!123456");

通过阅读MySQL JDBC的 源代码,本文将讲述这两段代码背后的内容

1. Class.forName做了什么?
2. java.sql.DriverManager.registerDriver(new Driver())做了什么?

下面详细介绍

1. Class.forName做了什么?

使用Class.forName()会将调用的类初始化,即调用class中的static块,并返回该类的Class对象。比如: com.mysql.jdbc.Driver中代码,当调用Class.forName(“com.mysql.jdbc.Driver”)时,Driver类中static部分就会被调用。

static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}

2. java.sql.DriverManager.registerDriver(new Driver())做了什么?
在开始介绍之前先说明2点
(1) com.mysql.jdbc.Driver 的构造函数new Driver()是空的。
(2) 给DriverManager设置一个LogWriter, 可以看到更多log信, DriverManager.setLogWriter(new java.io.PrintWriter(System.out));

其实registerDriver方法做的事情很简单, registerDriver先初始化自己,然后将Driver实例添加到DriverManager中的2个Vector中:readDrivers, writeDrivers

3. DriverManager.getConnection做了什么?
遍历readDrivers, 找到合适的JDBC Driver然后调用其connect方法得到连接,具体怎么得到的连接,我们下一篇文章中将介绍。

下面通过两个例子说明这两个接口
例子1:查看DriverManager.getConnection()log
比如我注册了两个Driver, 一个是Sybase的JDBC Driver,一个是MySQL的JDBC Driver

Class.forName("com.sybase.jdbc2.jdbc.SybDriver");
Class.forName("com.mysql.jdbc.Driver"); DriverManager.getConnection("jdbc:mysql://localhost/quickstart", "root", "!QAZxsw2");

运行这段代码,你可以看到如下log (记得在这段代码前设置LogWriter, DriverManager.setLogWriter(new java.io.PrintWriter(System.out));)

static init
DriverManager.initialize: jdbc.drivers = null
JDBC DriverManager initialized
registerDriver: driver[className=com.sybase.jdbc2.jdbc.SybDriver,com.sybase.jdbc2.jdbc.SybDriver@42e816]
registerDriver: driver[className=com.mysql.jdbc.Driver,com.mysql.jdbc.Driver@de6ced]

java.sql.DriverManager.registerDriver(new Driver())
DriverManager.getConnection("jdbc:mysql://localhost/quickstart")
    trying driver[className=com.sybase.jdbc2.jdbc.SybDriver,com.sybase.jdbc2.jdbc.SybDriver@42e816]
    trying driver[className=com.mysql.jdbc.Driver,com.mysql.jdbc.Driver@de6ced]
 //遍历每个注册过得Driver,这里MySQL Driver在第二个,所以第二次才成功

getConnection returning driver[className=com.mysql.jdbc.Driver,com.mysql.jdbc.Driver@de6ced]

例子2:实现自己的JDBC 驱动

写一个MyDriver.java类,实现java.sql.Driver接口, MyConnection.java类,实现java.sql.Connection(1)在MyDriver.java中,类似com.mysql.jdbc.Driver中的static{}代码,注册自己
(2)并实现自己的acceptUrl,定义你的JDBC URL格式

//TODO,代码在另一台机器上,下次贴上。

运行以后,可以看到如下log信息

static init
DriverManager.initialize: jdbc.drivers = null
JDBC DriverManager initialized
registerDriver: driver[className=com.sybase.jdbc2.jdbc.SybDriver,com.sybase.jdbc2.jdbc.SybDriver@42e816]
registerDriver: driver[className=com.mysql.jdbc.Driver,com.mysql.jdbc.Driver@de6ced]
registerDriver: driver[className=com.mysql.jdbc.test.MyDriver,com.mysql.jdbc.test.MyDriver@1fb8ee3]//注册我自己写的驱动

java.sql.DriverManager.registerDriver(new MyDriver())
DriverManager.getConnection("jdbc:my_test_driver://localhost/quickstart") //我自己定义个格式
    trying driver[className=com.sybase.jdbc2.jdbc.SybDriver,com.sybase.jdbc2.jdbc.SybDriver@42e816]
    trying driver[className=com.mysql.jdbc.Driver,com.mysql.jdbc.Driver@de6ced]
    trying driver[className=com.mysql.jdbc.test.MyDriver,com.mysql.jdbc.test.MyDriver@1fb8ee3]
//因为注册驱动的时候,我放在第三个,所以第三次的时候成功了。
return MyDriver okgetConnection returning driver[className=com.mysql.jdbc.test.MyDriver,com.mysql.jdbc.test.MyDriver@1fb8ee3]

下面是一种常见的方式---

Class.forName和registerDriver的区别的更多相关文章

  1. 反射中Class.forName()和classLoader的区别

    搞清楚两者之间区别前,我们来了解下类加载过程. 一.类加载过程 1.加载 通过一个类的全限定名来获取定义此类的二进制字节流. 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构. 在内存中生 ...

  2. 在Java的反射中,Class.forName和ClassLoader的区别

    前言 最近在面试过程中有被问到,在Java反射中Class.forName()加载类和使用ClassLoader加载类的区别.当时没有想出来后来自己研究了一下就写下来记录一下. 解释 在java中Cl ...

  3. Class.forName和ClassLoader.loadClass区别(转)

    Java中class是如何加载到JVM中的:1.class加载到JVM中有三个步骤    装载:(loading)找到class对应的字节码文件.    连接:(linking)将对应的字节码文件读入 ...

  4. 反射中,Class.forName 和 classloader 的区别

    https://blog.csdn.net/qq_27093465/article/details/52262340 java中class.forName()和classLoader都可用来对类进行加 ...

  5. 在 Java 的反射中,Class.forName 和 ClassLoader 的区别

    1. 解释 在java中Class.forName()和ClassLoader都可以对类进行加载.ClassLoader就是遵循双亲委派模型最终调用启动类加载器的类加载器,实现的功能是“通过一个类的全 ...

  6. Java反射中Class.forName和classloader的区别

    Java中Class.forName和classloader都可以用来对类进行加载. Class.forName除了将类的.class文件加载到jvm中之外,还会对类进行解释,执行类中的static块 ...

  7. Class.forName和ClassLoader的区别

    一 看名字就知道了,一个是类的创建,一个类加载器 二 再看下Class.forName源码,调用了ClassLoader @CallerSensitive public static Class< ...

  8. class.forName 和 classLoader的区别

    Java中的Class.forName()和ClassLoader都可以用来对类进行加载.Class.forName()除了将类的.class文件加载到JVM中 还会对类进行解释,执行类中的stati ...

  9. class.forName() 和 classLoader 的区别

    相同点:        java中class.forName() 和 classLoader 都可用来对类进行加载 不同店:        1.class.forName()除了将类的 .class ...

随机推荐

  1. windows下git命令的使用

    一.写在前面 关于git,出于自己的爱好,前段时间玩了一下,也自己上网查了一下资料,现简单记录一下,以备查看. 当然,本文并不是介绍配置git服务器的文章,而是以github服务器作为git的远程仓库 ...

  2. JDK居然还有Server和Client模式

    JDK这货居然还分Server和Client版本,但经过观察,据说从1.7+版本开始这两者运行的区别已经逐步减少了.所以接下来的分析没啥意义. 参考: http://www.oracle.com/te ...

  3. Oracle问题诊断过程常用SQL

    --查看临时表空间使用情况select tablespace_name ,sum(size_mb),sum(used_mb),round(sum(used_mb)/sum(size_mb),2) fr ...

  4. Accessing an element's parent with ElementTree(转)

    Today I ran across a situation where I needed to programmatically remove specific elements from a KM ...

  5. MFC小程序------01 代码管理器

    1.代码入库: 2.代码查找: 3.查看全部代码: 4.程序设置: 自己学习MFC写的一个小程序,当中还有很多功能还待完好,比方数据库的导入功能还没有写,但导出功能是能够用的,查找算法也不是非常好,还 ...

  6. Fast dev didn't succeed, trying another location

    Android 调试时,出现快盘加载失败问题.调试输出如下: Fast dev didn't succeed, trying another location 解决办法: 将项目属性->Andr ...

  7. Unity3d Http Get请求

    新浪微博的OpenAPI登录 public static IEnumerator LoginRequest(string userid, string passwd, Action<string ...

  8. redis分布式锁redisson

    原文:https://blog.csdn.net/Kincym/article/details/78697472 关于redisson的源代码请参考官网:https://github.com/redi ...

  9. Java读取properties配置文件经常用法

    在开发中对properties文件的操作还是蛮常常的.所以总结了几种操作方法,为后面的开发能够进行參考. 1.通过java.util.ResourceBundle类来读取 这边測试用到了枚举类进行传入 ...

  10. Java:字符串类简单的正则表达式

    class Test { public static void main(String[] args) { String str = "xia..as....yuan.com"; ...