1. 程式人生 > >Class.forName和registerDriver的區別

Class.forName和registerDriver的區別

http div .cn 通過 文章 函數 accep roo details

我們都知道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,[email protected]]
registerDriver: driver[className=com.mysql.jdbc.Driver,[email protected]]

java.sql.DriverManager.registerDriver(new Driver())
DriverManager.getConnection("jdbc:mysql://localhost/quickstart")
trying driver[className=com.sybase.jdbc2.jdbc.SybDriver,[email protected]]
trying driver[className=com.mysql.jdbc.Driver,[email protected]]
//遍歷每個註冊過得Driver,這裏MySQL Driver在第二個,所以第二次才成功

getConnection returning driver[className=com.mysql.jdbc.Driver,[email protected]]

例子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,[email protected]]
registerDriver: driver[className=com.mysql.jdbc.Driver,[email protected]]
registerDriver: driver[className=com.mysql.jdbc.test.MyDriver,[email protected]]//註冊我自己寫的驅動

java.sql.DriverManager.registerDriver(new MyDriver())
DriverManager.getConnection("jdbc:my_test_driver://localhost/quickstart") //我自己定義個格式
trying driver[className=com.sybase.jdbc2.jdbc.SybDriver,[email protected]]
trying driver[className=com.mysql.jdbc.Driver,[email protected]]
trying driver[className=com.mysql.jdbc.test.MyDriver,[email protected]]
//因為註冊驅動的時候,我放在第三個,所以第三次的時候成功了。
return MyDriver okgetConnection returning driver[className=com.mysql.jdbc.test.MyDriver,[email protected]]

下面是一種常見的方式---

技術分享

Class.forName和registerDriver的區別