4 回答

TA貢獻(xiàn)1803條經(jīng)驗(yàn) 獲得超6個(gè)贊
這個(gè)問題翻一下兩個(gè)類的源碼就可以很清楚的了解了。
不過首先你的明白Class.forName()的作用,這個(gè)是用來加載指定類的。
為什么需要手動去加載呢?正常情況下對于一個(gè)Java程序來說我們不需要去管某個(gè)類的加載,只需要在用來的時(shí)候import進(jìn)去即可,但是對于JDBC的設(shè)計(jì)是不一樣的,你可以從你的數(shù)據(jù)庫連接代碼中發(fā)現(xiàn),DriverManage在決定使用哪個(gè)驅(qū)動的時(shí)候并不是由開發(fā)者指定的,而是通過遍歷所有已注冊的驅(qū)動來嘗試獲取連接,成功就返回,失敗就next,所以代碼中并沒有顯示的指定驅(qū)動,這一點(diǎn)可以從DriverManage的源碼中可以看到。
for(DriverInfo aDriver : registeredDrivers) {
// If the caller does not have permission to load the driver then
// skip it.
if(isDriverAllowed(aDriver.driver, callerCL)) {
try {
println(" trying " + aDriver.driver.getClass().getName());
Connection con = aDriver.driver.connect(url, info);
if (con != null) {
// Success!
println("getConnection returning " + aDriver.driver.getClass().getName());
return (con);
}
} catch (SQLException ex) {
if (reason == null) {
reason = ex;
}
}
} else {
println(" skipping: " + aDriver.getClass().getName());
}
}
這個(gè)類基本可以明白JDBC是如何獲取連接的,問題是registeredDrivers是怎么來的,從DriverManager的源碼中只能夠發(fā)現(xiàn)一個(gè)registerDriver方法可以往registeredDrivers中注冊驅(qū)動,所以自然是由驅(qū)動類自行將自己注冊到registeredDrivers中,這一點(diǎn)可以通過查看com.mysql.jdbc.Driver類源碼得到證實(shí)。
//
// Register ourselves with the DriverManager
//
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
這個(gè)是jdbc.Driver的一段static代碼,這段代碼在類加載時(shí)會自動執(zhí)行,所以就把自己注冊到DriverManage的registerDriver中了,這樣整個(gè)流程就全部通了。
綜上,不懂得問題翻翻代碼就清楚了,多動手。

TA貢獻(xiàn)1772條經(jīng)驗(yàn) 獲得超6個(gè)贊

TA貢獻(xiàn)1854條經(jīng)驗(yàn) 獲得超8個(gè)贊
class.forName("com.mysql.jdbc.Driver")會在classpath中查找并加載這個(gè)類。一旦com.mysql.jdbc.Driver被加載并連接后,就自動執(zhí)行static靜態(tài)代碼塊,這時(shí)就可以做一些初始化的工作了,最主要的作用就是執(zhí)行java.sql.DriverManager.registerDriver()來注冊驅(qū)動。如果沒有class.forName這一步,就會報(bào)找不到合適的驅(qū)動程序。

TA貢獻(xiàn)1851條經(jīng)驗(yàn) 獲得超4個(gè)贊
通過反射機(jī)制加載數(shù)據(jù)庫驅(qū)動類。
不然誰知道你鏈接的是哪個(gè)數(shù)據(jù)庫啊。。。
添加回答
舉報(bào)