Class.forName和registerDriver的区别
我们都知道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]
下面是一种常见的方式---