MySQL JDBC驅動 - Class.forName和java.sql.DriverManager.registerDriver (new Driver())的區別

MySQL JDBC驅動 - 01 - Class.forName

我們都知道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]

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章