12

JDBC のバージョン 4 で追加された優れた機能の 1 つは、呼び出しによってドライバーを明示的にロードする必要がClass.forNameなくなりました。アプリケーションが初めてデータベースに接続しようとするとDriverManager、アプリケーションで見つかったドライバが自動的にロードされますCLASSPATH

私の質問はどうですか?クラスパスに複数のドライバーがある場合はどうなりますか?

私が推測できることの1つは、接続URLを解析すると、必要なドライバーがJDBCであるかODBCであるかを判断できるということですが、複数のjdbc準拠ドライバーから、使用しているデータベースに選択するドライバーをどのように判断できますか? (MySql を使用していて、MySql-Connector ドライバーが必要だとしましょう)。JVM にそのようなデータベース ドライバの静的マッピングはありますか?

4

3 に答える 3

19

すべての JDBC 4 準拠のドライバーには、その jar に というファイルがあり、そのMETA-INF/services/java.sql.Driverファイルには の実装がリストされますjava.sql.Driver。接続を要求すると、DriverManagerは を使用してクラスパス内の のServiceLoaderすべての (!) コピーを検索し、リストされているすべてのクラスをロードします。クラスがロードされると、それ自体を に登録する必要があるMETA-INF/services/java.sql.Driverため、はサービス ローダーを使用してすべてのクラスをロードし、各実装はそれ自体を登録します。java.sql.DriverDriverManagerDriverManagerDriver

からの接続を要求するとDriverManager、 はDriverManager登録済みのすべてのドライバに対して反復処理を行い、Connection. "jdbc:firebirdsql:"ドライバーは、JDBC URL を使用して、それがサポートするプロトコルであるかどうかを確認します (たとえば、Jaybird/Firebird JDBC は、URL がまたはで始まるかどうかを確認します"jdbc:firebird:")。ドライバーがプロトコルをサポートしていない場合は を返します。プロトコルをnullサポートしている場合は、確立された接続を返すか、または をスローしSQLExceptionます (たとえば、URL でエラーが発生した場合、または接続できなかった場合)。 . すべてのドライバーが返された場合null(プロトコルをサポートするドライバーがない場合)、with エラーDriverManagerがスローされます。SQLException"No suitable driver found for <url>"

そのため、クラスパスに複数のドライバーがあっても、それらが異なるプロトコルをサポートしている限り問題ありませんが、同じデータベース (または少なくとも同じプロトコルプレフィックス) に複数のドライバーがある場合は、ドライバーのリストの最初のものを使用します。Java のバージョンによっては、そのドライバーがSQLException.

于 2013-08-18T08:54:17.723 に答える
12

から取得した JDBC4 ドライバーのロードに関する情報: http://www.onjava.com/2006/08/02/jjdbc-4-enhancements-in-java-se-6.html

メソッド getConnection が呼び出されると、DriverManager は、初期化時にロードされた JDBC ドライバーと、現在のアプリケーションと同じクラス ローダーを使用して明示的にロードされた JDBC ドライバーの中から適切なドライバーを見つけようとします。

DriverManager メソッド getConnection および getDrivers が拡張され、Java SE Service Provider メカニズム (SPM) をサポートするようになりました。SPM によると、サービスは既知のインターフェイスと抽象クラスのセットとして定義され、サービス プロバイダーはサービスの特定の実装です。また、サービス プロバイダーの構成ファイルが META-INF/services ディレクトリに格納されることも指定します。JDBC 4.0 ドライバーには、ファイル META-INF/services/java.sql.Driver が含まれている必要があります。このファイルには、JDBC ドライバーの java.sql.Driver の実装の名前が含まれています。たとえば、JDBC ドライバーをロードして Apache Derby データベースに接続するには、META-INF/services/java.sql.Driver ファイルに次のエントリを含めます。

org.apache.derby.jdbc.EmbeddedDriver

今あなたの質問に来ます。

私の質問はどうですか?クラスパスに複数のドライバーがある場合はどうなりますか?

クラス・ローダーのルールとして、最初に見つかったクラスがロードされ、すでにロードされている場合は、クラス・ローダーによって再ロードされません。

于 2013-08-17T11:06:35.443 に答える