2013-08-17 87 views
11

JDBC4版本中的一個很好的補充您不必通過調用Class.forName來明確加載 驅動程序。當您的應用程序首次嘗試連接數據庫時,DriverManager會自動加載在 應用程序CLASSPATH中找到的驅動程序。JDBC4中驅動程序類的位置

我的問題是怎麼回事?如果類路徑中有多個驅動程序會怎麼樣?

我可以猜測的一件事是,解析連接URL是否需要驅動程序是JDBC或ODBC,但是怎麼能說出多個jdbc兼容的驅動程序哪一個將被選擇用於數據庫I正在使用? (可以說我正在使用MySql,我需要MySql-Connector驅動程序)。 JVM中是否存在這種數據庫驅動程序的靜態映射?

+0

爲什麼你需要一個驅動程序? –

+2

你還會連接到數據庫嗎?傳統上我們做Class.ForName(驅動程序)。 –

+0

@atamanroman我沒有什麼可以向你解釋的,你的話不要說出來。 –

回答

10

約JDBC4驅動加載一些信息摘自:http://www.onjava.com/2006/08/02/jjdbc-4-enhancements-in-java-se-6.html

當調用getConnection方法時,DriverManager將將 試圖從JDBC驅動程序 是在初始化以及裝載之間找到一個合適的驅動程序明確使用與當前應用程序相同的類加載器加載。

已增強DriverManager方法getConnection和getDrivers以支持Java SE服務提供者機制(SPM),其中增強了 。 根據SPM,服務被定義爲着名的一組接口和抽象類,而服務提供者是特定的 服務的實現。它還指定服務提供商配置文件 存儲在META-INF/services 目錄中。 JDBC 4.0驅動程序必須包含文件 META-INF/services/java.sql.Driver。該文件包含 JDBC驅動程序的java.sql.Driver實現的名稱。例如,要加載 JDBC驅動程序連接到Apache Derby數據庫,該 META-INF /服務/ java.sql.Driver文件需要包含以下 項:

org.apache.derby.jdbc.EmbeddedDriver 

現在來你的問題。

我的問題是怎麼回事?如果 類路徑中有多個驅動程序會怎麼樣?

作爲一個類加載器規則,首先找到的任何類都將被加載,並且如果它已經被加載,那麼將不會被類加載器重新加載。

10

每個JDBC 4兼容的驅動程序在其名爲META-INF/services/java.sql.Driver的jar中有一個文件,在該文件中它將列出其實現java.sql.Driver。當您請求連接時,DriverManager將使用ServiceLoader在類路徑中查找META-INF/services/java.sql.Driver的所有(!)副本,然後將加載列出的所有類。當加載一個java.sql.Driver類時,它必須自己註冊DriverManager,所以DriverManager使用服務加載器加載所有類,並且每個Driver實現註冊自己。

當您從DriverManager請求連接時,DriverManager將遍歷所有已註冊的驅動程序,要求它們輸入Connection。驅動程序將使用JDBC URL檢查它支持的協議(例如,Jaybird/Firebird JDBC檢查URL是否以"jdbc:firebirdsql:""jdbc:firebird:"開頭)。如果驅動程序不支持該協議,它將返回null,如果它支持該協議,它將返回一個已建立的連接,或者它將拋出一個SQLException(例如,如果您在URL中發生錯誤,或者它不能連接)。如果所有的驅動程序返回null(沒有支持該協議),然後DriverManager將拋出一個SQLException錯誤"No suitable driver found for <url>"

因此,有類路徑上的多個驅動器不只要它們支持不同的協議的事情,但是如果有多個驅動程序相同的數據庫(或者至少:相同的協議前綴),它將使用驅動程序列表中的第一個,如果該驅動程序失敗並且使用SQLException,則它不會嘗試另一個驅動程序。

0

在JDBC 4中,驅動程序會自動註冊。這是怎麼發生的? 當我們寫

Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/sonoo","root","root"); 

這將調用DriverManager類中的靜態塊。如果你打開DriverManager的源文件,你可以看到靜態塊

static { 
     loadInitialDrivers(); 
     println("JDBC DriverManager initialized"); 
    } 

這將調用函數loadInitialDrivers();功能並加載所有驅動程序和自動註冊。所以我們不需要明確註冊或加載驅動程序。

相關問題