我們都知道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]
后續: 解讀com.mysql.jdbc.Driver.connect()的實現