Каково фактическое использование Class.forName("oracle.jdbc.driver.OracleDriver")
при подключении к базе данных? почему мы не можем импортировать тот же класс, вместо этого мы загружаем его.
Почему мы используем Class.forName( "oracle.jdbc.driver.OracleDriver" ) при подключении к базе данных?
Ответ 1
Основная идея использования Class.forName()
заключается в загрузке реализации драйвера JDBC. A (нормальный) JDBC-драйвер должен содержать статический инициализатор, который регистрирует экземпляр реализации драйвера с помощью java.sql.DriverManager
:
Драйверы JDBC должны реализовывать интерфейс
Driver
, и реализация должна содержать статический инициализатор, который будет вызываться при загрузке драйвера. Этот инициализатор регистрирует новый экземпляр себя с помощьюDriverManager
(из JDBC 4.1, раздел 9.2)
Поскольку JDBC 4.0, однако, существует новый способ регистрации драйверов: в jar драйвера JDBC должен быть включен файл /META-INF/services/java.sql.Driver
, который содержит имена (имена) реализаций java.sql.Driver
в этой банке. Когда вы создаете соединение с помощью DriverManager
, он будет использовать java.util.ServiceLoader
для перечисления всех файлов /META-INF/services/java.sql.Driver
в пути к классам и загрузки всех драйверов, чтобы они регистрировались.
Метод
DriverManager.getConnection
был расширен для поддержки механизма поставщика услуг Java Standard Edition. Драйверы JDBC 4.0 должны включать файлMETA-INF/services/java.sql.Driver
. Этот файл содержит имя реализации JDBC-драйверовjava.sql.Driver
.
(из JDBC 4.1, раздел 9.2.1)
Драйверы причин загружаются таким образом, что он позволяет отделить приложение от используемого драйвера (и базы данных). Это означает, что вы можете писать, компилировать и даже распространять приложение без каких-либо драйверов, вам нужно использовать только интерфейсы, предоставляемые в пакете java.sql
(и javax.sql
) - который является частью Java - без необходимости доступа к реализации непосредственно.
Пользователь приложения затем добавляет действительный драйвер JDBC в путь к классам (и настраивает такие вещи, как строка подключения), чтобы приложение действительно могло подключаться к базе данных. Перед JDBC 4.0 пользователь должен будет указать имя драйвера, чтобы приложение могло загружать его с помощью Class.forName
, с совместимым с JDBC драйвером и Java 6 или выше это открытие было автоматическим.
Когда вы загружаете драйвер буквально с помощью Class.forName("oracle.jdbc.driver.OracleDriver")
, это может показаться излишним, но если вы помните, что это также может быть строка, вытащенная из файла конфигурации (или с пользовательского ввода), вы можете начать понимать, почему это настолько силен.
Конечно, эта независимость от драйверов не составляет 100%, особенно если ваше приложение использует специфический для поставщика SQL. Но теория заключается в том, что ваше приложение может быть независимым от базы данных. JDBC также предоставляет некоторые дополнительные механизмы для решения этой проблемы, например, JDBC-экраны, чтобы обеспечить общий синтаксис, который драйвер переводит на конкретный синтаксис, и DatabaseMetaData
, который позволяет вам обнаруживать функции, зарезервированные слова и т.д., Которые позволяют создавать или генерировать совместимые запросы.
Ответ 2
Это унаследованный способ сделать это. При импорте класса у вас будет дополнительная зависимость
Из учебника Java:
В предыдущих версиях JDBC, чтобы получить соединение, вам сначала пришлось инициализируйте свой JDBC-драйвер, вызвав метод Class.forName. Эта методам нужен объект типа java.sql.Driver. Каждый драйвер JDBC содержит один или несколько классов, реализующих интерфейс java.sql.Driver.
...
Любые драйверы JDBC 4.0, которые находятся в вашем классе путь автоматически загружаются. (Однако вы должны вручную загрузить любой драйверов до JDBC 4.0 с помощью метода Class.forName.)
Ответ 3
Пара причин использовать Class.forName("")
вместо прямого ссылки на класс напрямую:
-
Использование
Class.forName("")
дает вам более очевидный контроль над тем, где именно первая попытка загрузить указанный класс будет выполнена в вашем коде. Это делает его более очевидным, если код не сработает (генерирует исключение), если этот класс отсутствует в пути к классам при запуске этого кода. -
Если вы просто импортируете класс и затем ссылаетесь на него в своем коде, он становится несколько менее очевидным, если код будет генерировать исключение, если класс отсутствует.
-
Кроме того, использование
Class.forName("")
- это способ обойти потенциальные ограничения времени компиляции. Если, например, лицо, компилирующее код, не имеет права доступа (например, по лицензированию или интеллектуальной собственности) к классу oracle.jdbc.driver.OracleDriver, им может быть проще скомпилировать код, который ссылается на класс поClass.forName("")
, а не напрямую. -
Если вам не нужно использовать какие-либо методы, поля или внутренние классы указанного класса, то
Class.forName("")
может быть самым ясным способом выразить, что единственное, что нужно - загрузить класс (и запускаются его статические инициализаторы), и ничего больше.
Я не думаю, что Class.forName демонстрирует любое другое функциональное поведение, чем непосредственное обращение к классу. Он по умолчанию использует класс-загрузчик классов, который должен быть тем же загрузчиком классов, который используется при непосредственном обращении к классу. Есть несколько перегрузок в Class.forName(""), которые позволяют немного настраивать поведение загрузки классов.
Ответ 4
Иногда требуется загрузить класс во время выполнения. т.е. любой класс может динамически загружаться в ячейку памяти при выполнении приложения java. Class.forName
используется для загрузки любого заданного класса (в двойных кавычках как String) во время выполнения. Например, когда мы используем IDE, мы видим, что будет построитель GUI, который позволяет нам перетаскивать кнопки, текстовые поля и т.д. Этот механизм перетаскивания изнутри требует, чтобы определенные классы загружались во время выполнения.
В Class.forName(sun.jdbc.odbc.JdbcOdbcDriver
) класс относится к пакету java.lang.Class
, а forName()
- статический метод java.lang.Class
. Драйверы JDBC (String) будут динамически загружаться в класс во время выполнения, а метод forName содержит статический блок, который создает объект класса драйвера и автоматически регистрируется с помощью службы DriverManager
. Поскольку forName()
является статическим, мы вызываем его, используя имя класса (класс).
Ответ 5
Class.forName( "oracle.jdbc.driver.OracleDriver" ) принимает имя класса как строковый аргумент и загружает его в память. Второй способ загрузки класса - просто создать экземпляр с помощью new
. Недостатком второго метода является то, что новый экземпляр будет бесполезен, если он вам не нужен.
В хорошем учебнике объясняется Основы подключения JDBC.
Ответ 6
Когда мы хотим выполнить статический блок класса, не создавая его объект, мы можем использовать class.forName()
. Большая часть работы, выполняемой классом Driver
, существует в ее статическом блоке.
Теперь то, что нам требуется в нашей JDBC-подключении, - это получить драйвер, зарегистрированный с помощью DriverManager
, и получить с ним соединения, так что это может быть достигнуто просто путем запуска статического блока и нет необходимости создавать объект этого класса, Такой подход даст лучшую производительность.
Ответ 7
Это используется для того, чтобы открыть класс или, другими словами, вызвать его через его имя из строкового формата.
Например:
Class.forName("com.android.example.MainClass");
И он запустит класс внутри пакета com/android/example/MainClass.java