我们都知道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. HAproxy和TIME WAIT的一次问题排查

    近日平稳运行了将近4年的发号器突然出现问题,在元旦0分的时候出现短暂的性能下降,导致发号失败率飙高到一个不可接收的值,哎,意外总是发生在你想不到的地方. 这几天赶紧和小伙伴们赶紧追查原因,制定改造方案 ...

  2. Running CMD.EXE as Local System(转)

    Many times in the past I had to run an interactive command-line shell under the Local SYSTEM account ...

  3. SYSCALL_DEFINE3

    http://blog.csdn.net/yueyingshaqiu01/article/details/48786961

  4. 通过内存盘提高MSMQ的消息吞吐能力

    转载:http://www.ikende.com/blog/00f2634be4704b79a3e22439edeb1343 由于MSMQ的消息交互都需要对磁盘进行读写操作,所以提高MSMQ的消息吞吐 ...

  5. java基础学习总结——哈希编码

    一.哈希编码

  6. Oracle学习中,重点是sql语句的学习,而所有的sql语句都要在scott用户下完成。

    熟悉这个用户下的四张表,是必要的. 查看所有表名: SELECT * FROM tab; 查看每张表的结构: DESC 表名称: 1.部门表:dept no  名称 类型 描述 1 DEPTNO NU ...

  7. Spring-3.2.5 + Quartz-2.2.1 集群实例(Tomcat+Memcached+Quartz集群session共享)

    本例中我启动了两个Tomcat作效果测试,先看效果图: 现在我们关闭一个Tomcat 注意红线的位置和设置的参数有关 #org.quartz.jobStore.clusterCheckinInterv ...

  8. iOS获取网络类型的四种方法

    Reachability类只能区分WIFI和WWAN类型,却无法区分2G网和3G网. 网上也有些方法,却都存在Bug. 经过网上查找资料和测试,基本上总结了以下几种方法: 1.使用导航栏的方式:(私有 ...

  9. pgm转jpg

    clc;clear all;for i=1:40for j=1:10image=imread(strcat('N:\FACE\orl_faces\s',...int2str(i),'\',int2st ...

  10. u-boot支持yaffs映像烧写的补丁

    u-boot的nand flash驱动有两个版本,似乎是以u-boot1..5为分界点的,之前的版本使用的是自己写的nand flash驱动,而后面的版本使用的是linux内核中nand flash的 ...