2011-10-05 36 views
17

Entiendo que la carga de clase es útil para cargar la clase en tiempo de ejecución con su nombre de clase.¿Cuál es el propósito de 'Class.forName ("MY_JDBC_DRIVER")'?

Sin embargo, mientras usamos JDBC en nuestro proyecto, sabemos qué controlador vamos a utilizar y, en su mayoría, la cadena del administrador de controladores está codificada.

Mi pregunta es: ¿Por qué estamos cargando el controlador usando Class.forName("JDBC_DRIVER") aquí?
¿Por qué no podemos continuar agregando el controlador en la ruta de clase? ya que sabemos qué contenedor de controladores vamos a usar.

Creo que Class.forName(JDBC_DRIVER) cargará el controlador en DriverManager. ¿Es la única razón?

Editar 1:

Los DriverManager API doc estados que

Como parte de su inicialización (DriverManager), la clase DriverManager intentará cargar las clases controlador de referencia en las "jdbc.drivers" propiedad del sistema.

Las aplicaciones ya no necesitan cargar explícitamente los controladores JDBC usando Class.forName(). Los programas existentes que actualmente cargan controladores JDBC usando Class.forName() continuarán funcionando sin modificaciones.

Luego cuando uso otro que el controlador oracle; ¿Necesito cambiar la cadena del nombre del controlador en la propiedad del sistema?

+0

Grupo, gracias. Ahora entiendo que class.forName() es útil para cargar una clase en comparación con otros mecanismos, como llamar a su método estático o crear una instancia de esa clase. De esta forma podemos asegurarnos de ejecutar algunas funcionalidades solo una vez usando el bloque estático durante la carga. –

Respuesta

22

En primer lugar: con los controladores JDBC modernos y un JDK actual (al menos Java 6) la llamada a Class.forName() ya no es necesaria. JDBC driver classes are now located usando el service provider mechanism. Usted debería ser capaz de simplemente eliminar esa llamada y dejar el resto del código sin cambios y debería seguir funcionando.

Si usted no está usando un JDK actual (o si tiene un controlador JDBC que hace no tienen los archivos correspondientes establecidos para utilizar ese mecanismo) a continuación, el conductor tiene que estar registrados en el uso de DriverManagerregisterDriver. Ese método es generalmente llamado llamado desde el bloque de inicializador estático de la clase de controlador real, que se activa cuando la clase se carga por primera vez, por lo que emitir el Class.forName() garantiza que el controlador se registre solo (si no lo hizo).

Y no importa si utiliza Class.forName() o el nuevo mecanismo de proveedor de servicios, se le siempre necesitará el controlador JDBC en la ruta de clase (o disponibles a través de algún ClassLoader en tiempo de ejecución, por lo menos).

tl; dr: sí, el uso única de ese Class.forName() llamada es para asegurar que el conductor se ha registrado. Si utiliza un JDK actual y controladores JDBC actuales, entonces esta llamada ya no será necesaria.

+1

¡Sí! en java6 sin la línea Class.forName(); DriverManager puede crear Connection para el controlador oracle. Acabo de probar. Se realiza a través de loadInitialDrivers() :: DriverManager. ¡Gracias! –

+0

@Joachim, el comentario de JustinK http://stackoverflow.com/questions/8053095/what-is-the-actual-use-of-class-fornameoracle-jdbc-driver-oracledriver-while#comment-9863309 indica que en cuanto a pre JDBC 4, 'Class.forName' ** solo es necesario cuando ** el controlador no se encuentra en la ruta de clases. ¿Por qué el comentario de JustinK contradice directamente su cita que dice que "siempre necesitaremos el controlador JDBC en el classpath"? – Pacerier

+0

@Pacerier: JustinK está hablando de tener el controlador en el classpath * mientras construyes tu código *. Eso nunca debería ser necesario a menos que de alguna manera acceda a la clase de controlador directamente (lo que puede necesitar, tiene acceso a algunas características no estándar, pero es bastante improbable de lo contrario). En tiempo de ejecución, necesita tener el controlador en el classpath (o tal vez en un cargador de clases personalizado, si lo prefiere, pero eso es prácticamente lo mismo) sin importar cómo acceda, de lo contrario no podría cargarse. –

12

El Class.forName (JDBC_DRIVER) llamada va a registrar su controlador JDBC en el DriverManager, por lo que puede hacerle frente por URL, como "jdbc: odbc: Base de datos" y así sucesivamente ...

lo general, el clase del controlador tiene el código de inicialización estática como éste, que se invoca en Class.forName():

public class Driver implements java.sql.Driver { 
    static { 
    try { 
     DriverManager.registerDriver(new Driver()); 
    } catch (SQLException E) { 
     throw new RuntimeException("Can't register driver!"); 
    } 
    } 
} 

Usted todavía tiene que poner JDBC controlador jar en la ruta de clase.

Como alternativa, puede usar el DataSource específico de la base de datos, luego puede declarar declarativamente el tipo de fuente de datos, por ejemplo en el contexto Spring o en el servidor web JNDI. Aquí hay un example.

+2

técnicamente esto se invoca cuando se carga la clase, no necesariamente en 'Class.forName()' que es solo una forma de forzar la carga de una clase descargada. –

4

Poner una clase en el classpath no es suficiente para que el cargador de clases lo cargue. Y la clase de controlador debe cargarse para garantizar que esté registrada en la API de JDBC. Por cierto, para que Class.forName funcione, la clase de controlador debe estar en el classpath.

2

En muchas aplicaciones industriales, nos gustaría abstraer la capa de acceso a datos del resto de código, tirando de dicha información en forma de archivo de propiedades/archivo de configuración. En esos casos, podríamos necesitar usar algo como lo has hecho.

Por ej. podemos usar las clases de interfaz JDBC para escribir el código para acceder a la base de datos, donde puede configurar las propiedades seleccionando qué tecnología desea usar como base de datos (por ejemplo, controlador ojdbc, o controlador mysql jdbc, etc.) En esos casos, puede cargar la clase usando dicho método.

Cuestiones relacionadas