Как на самом деле используется Class.forName («oracle.jdbc.driver.OracleDriver») при подключении к базе данных?

93

Что будет команда

Class.forName("oracle.jdbc.driver.OracleDriver")

точно делать при подключении к базе данных Oracle? Есть ли другой способ сделать то же самое?

Аравинд
источник
6
Связано: stackoverflow.com/questions/5992126/loading-jdbc-driver Обратите внимание, что вам нужно вызвать его только один раз , во время запуска вашего приложения; вам не нужно вызывать его каждый раз перед установлением соединения во время жизни приложения.
BalusC 08
@BalusC Предположим, у меня есть сведения о подключении в отдельном классе, Aгде я вызываю конструктор Class.forName("oracle.jdbc.driver.OracleDriver")класса A, и я создаю A'sобъект для получения поля подключения для каждого сервлета, где мне нужно подключение, тогда java пропустит Class.forName("oracle.jdbc.driver.OracleDriver")или загрузится снова?
Асиф Муштак

Ответы:

71

Он получает ссылку на объект класса с FQCN (полное имя класса) oracle.jdbc.driver.OracleDriver.

Он ничего не «делает» с точки зрения подключения к базе данных, кроме обеспечения того, чтобы указанный класс был загружен текущим загрузчиком классов . Нет принципиальной разницы между написанием

Class<?> driverClass = Class.forName("oracle.jdbc.driver.OracleDriver");
// and
Class<?> stringClass = Class.forName("java.lang.String");

Class.forName("com.example.some.jdbc.driver")вызовы отображаются в устаревшем коде, который использует JDBC, потому что это устаревший способ загрузки драйвера JDBC .

Из учебника по Java :

В предыдущих версиях JDBC для получения соединения сначала нужно было инициализировать драйвер JDBC, вызвав метод Class.forName. Этим методам требуется объект типа java.sql.Driver. Каждый драйвер JDBC содержит один или несколько классов, реализующих интерфейс java.sql.Driver.
...
Любые драйверы JDBC 4.0, обнаруженные в пути к вашему классу, загружаются автоматически. (Однако вы должны вручную загрузить любые драйверы до JDBC 4.0 с помощью этого метода Class.forName.)

Дальнейшее чтение (читайте: вопросы это дублирование)

Мэтт Болл
источник
29
Другими словами, он позволяет использовать класс Driver без явного импорта для вашего класса. Это позволяет создавать проект без необходимости наличия драйвера Oracle в пути к классам.
JustinKSU
3
Однако следует отметить, что «традиционным способом» вы вызываете Class.forName()без захвата ссылки на возвращаемый driverClass, поэтому на первый взгляд это кажется бездействующей операцией
matt b
11
Это связано с тем, что драйвер JDBC должен иметь статический инициализатор, который регистрирует драйвер с помощью DriverManager. При использовании Class.forName () этот инициализатор выполняется и драйвер регистрируется. Начиная с JDBC 4.0, DriverManager сам использует ServiceLoader для поиска драйверов в пути к классам.
Марк Роттевил 08
1
@MattBall, Что касается версий до JDBC 4.0, получение ссылки на драйвер или вызов статической функции этого класса драйвера уже автоматически загружает класс драйвера. Так зачем это делать вручную Class.forName("etc.driver")?
Pacerier
1
@Pacerier неверное предположение. JDBC не знает, какой драйвер вы хотите загрузить, поэтому в JDBC (который не зависит от драйвера) нет ничего, что могло бы сослаться на класс драйвера. Итак, вам нужно что-то, что запускает загрузку класса. Полагаю, что вместо Class.forName(...).
Мэтт Болл
13

Регистрирует водителя; что-то в форме:

public class SomeDriver implements Driver {
  static {
    try {
      DriverManager.registerDriver(new SomeDriver());
    } catch (SQLException e) {
      // TODO Auto-generated catch block
    }
  }

  //etc: implemented methods
}
Макдауэлл
источник
6

Из учебника Java JDBC :

В предыдущих версиях JDBC для получения соединения сначала нужно было инициализировать драйвер JDBC, вызвав метод Class.forName . Все драйверы JDBC 4.0, обнаруженные в пути к классу, загружаются автоматически. (Однако вы должны вручную загрузить все драйверы до JDBC 4.0 с помощью этого метода Class.forName.)

Итак, если вы используете драйвер Oracle 11g (11.1) с Java 1.6, вам не нужно вызывать Class.forName. В противном случае вам нужно вызвать его для инициализации драйвера.

Джонатан
источник
1
@Jonathan, что вы имеете в виду под "вручную загружать любые драйверы до JDBC 4.0 с помощью метода Class.forName", не могли бы вы объяснить?
Aravind
В Class.forNameсилах вызова загрузчик классов для загрузки данного класса. Это шаг ручной загрузки, описанный в руководстве.
Джонатан
@Jonathan Так вот почему мое соединение все еще работает без class.forName();:)
Асиф Муштак,
2

До Java 6 DriverManagerкласс не знал, какой драйвер JDBC вы хотите использовать.Class.forName("...")был способ предварительной загрузки классов драйверов.

Если вы используете Java 6, вам больше не нужно этого делать.

Qwerky
источник
Да, нужно использовать: OracleDataSource now docs.oracle.com/cd/B28359_01/java.111/b31224/urls.htm#i1070726, и он сам создает URL: final OracleDataSource ds = new OracleDataSource (); ds.setDriverType ("тонкий"); ds.setServerName (имя хоста); ds.setPortNumber (порт); //ds.setDatabaseName(dbName); ds.setServiceName (dbName); соединение = ds.getConnection (пользователь, pwd);
Rajesh Goel
1

Эта команда загружает класс драйвера Oracle jdbc, который будет доступен для экземпляра DriverManager. После загрузки класса система может подключиться к Oracle с его помощью. В качестве альтернативы вы можете использовать метод registerDriver в DriverManager и передать его с экземпляром необходимого драйвера JDBC.

анатолич
источник
0

Используйте oracle.jdbc.OracleDriver, а не oracle.jdbc.driver.OracleDriver. Вам не нужно регистрировать его, если файл jar драйвера находится в каталоге «WEB-INF \ lib», если вы используете Tomcat. Сохраните его как test.jsp и поместите в свой веб-каталог, а затем повторно разверните папку веб-приложения в диспетчере Tomcat:

<%@ page import="java.sql.*" %>

<HTML>
<HEAD>
<TITLE>Simple JSP Oracle Test</TITLE>
</HEAD><BODY>
<%
Connection conn = null;
try {
    Class.forName("oracle.jdbc.OracleDriver");
    conn = DriverManager.getConnection("jdbc:oracle:thin:@XXX.XXX.XXX.XXX:XXXX:dbName", "user", "password");
    Statement stmt = conn.createStatement();
    out.println("Connection established!");
}
catch (Exception ex)
{
    out.println("Exception: " + ex.getMessage() + "");

}
finally
{
    if (conn != null) {
        try {
            conn.close();   
        }
        catch (Exception ignored) {
            // ignore
        }
    }
}

%>
Том
источник