Как класс драйвера находится в JDBC4

Одно из замечательных дополнений в версии 4 JDBC. Вам не нужно явно загружать драйвера, вызвав Class.forName больше. Когда приложение пытается подключиться к базе данных впервые, DriverManager автоматически загружает драйвер, найденный в приложение CLASSPATH.

Мой вопрос: как? Что делать, если в пути к классам имеется несколько драйверов?

Одна вещь, которую я могу догадаться, состоит в том, что при разборе URL-адреса соединения, нужен ли драйвер JDBC или ODBC, можно выяснить, но как можно сказать из нескольких драйверов, совместимых с jdbc, которые нужно выбрать для базы данных, которую я использую? (скажем, я использую MySql, и мне нужен драйвер MySql-Connector). Есть ли статическое сопоставление таких драйверов базы данных в JVM?

Ответ 1

Некоторая информация о загрузке драйвера 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/услуги/java.sql.Driver. Этот файл содержит имя Драйвер JDBC для java.sql.Driver. Например, чтобы загрузить драйвер JDBC для подключения к базе данных Apache Derby, Файл META-INF/services/java.sql.Driver будет содержать следующие запись:

org.apache.derby.jdbc.EmbeddedDriver

Теперь на ваш вопрос.

Мой вопрос: как? Что делать, если в Путь к классам?

В качестве правила загрузчика класса, любой найденный первый класс будет загружен, а если он уже загружен, он не будет перезагружен загрузчиком классов.

Ответ 2

Каждый драйвер, совместимый с JDBC 4, имеет в своем jar файле файл с именем META-INF/services/java.sql.Driver, в котором он перечислит свои реализации java.sql.Driver. Когда вы запрашиваете соединение, DriverManager будет использовать ServiceLoader для поиска всех (!) META-INF/services/java.sql.Driver в пути к классам, а затем загрузит все перечисленные классы. Когда класс java.sql.Driver загружен, он должен зарегистрироваться в DriverManager, поэтому DriverManager загружает все классы, используя загрузчик служб, и каждая реализация Driver регистрирует себя.

Когда вы запрашиваете соединение от DriverManager, DriverManager будет перебирать все зарегистрированные драйверы, запрашивая у них Connection. Драйвер будет использовать URL JDBC для проверки того, поддерживает ли он протокол (например, JDBC Jaybird/Firebird проверяет, начинается ли URL с "jdbc:firebirdsql:" или "jdbc:firebird:"). Если драйвер не поддерживает протокол, он вернет значение null, если он поддерживает протокол, он либо вернет установленное соединение, либо выдаст SQLException (например, если вы допустили ошибку в URL-адресе или не смогли подключения). Если все драйверы возвращают null (ни один не поддерживает протокол), DriverManager сгенерирует DriverManager SQLException с ошибкой "No suitable driver found for <url>"

Таким образом, наличие нескольких драйверов на пути к классам не имеет значения, если они поддерживают разные протоколы, однако, если для одной и той же базы данных имеется несколько драйверов (или, по крайней мере: одинаковые префиксы протоколов), он будет использовать первый в списке драйверов. В зависимости от версии Java, если этот драйвер завершится с ошибкой SQLException, он продолжит работу со следующим драйвером (по крайней мере, Java 5 и выше) или прекратит попытки и сгенерирует исключение (я полагаю, это было в Java 1.4 или, возможно, даже раньше),

Ответ 3

В JDBC 4 драйверы регистрируются автоматически. Как это происходит? Когда мы пишем

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

это вызовет статические блоки внутри класса DriverManager. Если вы откроете исходный файл DriverManager, вы увидите статический блок

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

это вызовет функцию loadInitialDrivers(); и загрузит все драйверы и зарегистрируется автоматически. Поэтому нам не нужно явно регистрировать или загружать драйверы.