Controladores JDBC de Java
Tipos de controladores JDBC, carga de controladores en Java moderno y uso de DriverManager y DataSource para obtener conexiones.
Un controlador JDBC es la biblioteca suministrada por el proveedor que convierte las llamadas genéricas de java.sql en el protocolo de red específico que entiende una base de datos. La API JDBC es parte del JDK; el controlador es un JAR externo que se agrega al classpath. Sin controlador, no hay conexión.
Este capítulo cubre los cuatro tipos de controladores (y por qué solo uno importa hoy en día), cómo Java moderno carga controladores automáticamente sin Class.forName, la diferencia entre DriverManager y DataSource, y cómo DriverManager decide qué controlador gestiona una URL determinada. Para una visión más amplia de cómo encaja la API JDBC, consulta Introducción a JDBC en Java; para actuar sobre una conexión activa una vez que la tengas, consulta Conexión JDBC en Java.
Los cuatro tipos de controladores
La especificación JDBC define cuatro tipos históricos de controladores. En la práctica moderna casi siempre se usa el Tipo 4:
| Tipo | Nombre | Notas |
|---|---|---|
| 1 | Puente JDBC-ODBC | Obsoleto; eliminado del JDK en Java 8 |
| 2 | API nativa | Envuelve una biblioteca cliente C; requiere código nativo instalado |
| 3 | Protocolo de red | Habla con middleware que habla con la base de datos |
| 4 | Java puro (thin) | Un único JAR, todo Java, habla directamente el protocolo wire de la BD |
Los controladores de Tipo 4 — org.postgresql.Driver, com.mysql.cj.jdbc.Driver, el controlador H2 — son simplemente un JAR en el classpath. Eso es lo que se agrega a pom.xml o build.gradle. Como son Java puro, funcionan en cualquier plataforma donde corra la JVM, sin necesidad de instalar nada en la máquina anfitriona. Trata los tipos más antiguos como históricos: los verás en documentación antigua y en preguntas de examen, pero no los usarás en código nuevo.
Cargar un controlador: generalmente no hay que hacer nada
Los tutoriales antiguos muestran Class.forName("com.mysql.cj.jdbc.Driver"). Desde JDBC 4.0 (Java 6) esa línea es innecesaria. Los controladores incluyen un archivo META-INF/services/java.sql.Driver, y DriverManager los registra automáticamente mediante el mecanismo ServiceLoader la primera vez que llamas a getConnection. El código moderno es simplemente:
// No Class.forName needed — the driver JAR self-registers.
Connection conn = DriverManager.getConnection(
"jdbc:postgresql://localhost:5432/shop", "app", "secret");DriverManager vs. DataSource
Dos formas de obtener una conexión:
DriverManager.getConnection(url, user, password)— la más simple; adecuada para herramientas, scripts y demos. Abre una nueva conexión física en cada llamada.DataSource— el enfoque preferido para aplicaciones y servidores. UnDataSource(generalmente respaldado por un pool de conexiones como HikariCP) entrega conexiones en pool, por lo queclose()devuelve la conexión al pool en lugar de cerrar un socket.
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:postgresql://localhost:5432/shop");
ds.setUsername("app");
ds.setPassword("secret");
try (Connection conn = ds.getConnection()) { /* borrowed from the pool */ }La URL JDBC
Toda conexión comienza con una URL JDBC, que siempre tiene la forma jdbc:<subprotocol>:<subname>:
jdbc:postgresql://localhost:5432/shop
│ │ │
│ │ └─ subname: host, port, database, options
│ └───────────── subprotocol: identifies the vendor/driver
└────────────────── scheme: always "jdbc"El subprotocolo (postgresql, mysql, h2, oracle, sqlserver) es la parte que decide qué controlador gestiona la solicitud. Cada proveedor documenta su propio formato de URL y las opciones que siguen al nombre de la base de datos (configuración TLS, zona horaria, indicadores de conexión), así que consulta la documentación del controlador para la sintaxis exacta.
Cómo DriverManager elige un controlador
Cuando llamas a getConnection, DriverManager recorre su lista de controladores registrados y le pregunta a cada uno "¿reconoces esta URL?" mediante Driver.acceptsURL. Se usa el primero que responde afirmativamente; si ninguno lo hace, obtienes No suitable driver found. Un controlador normalmente responde "sí" solo cuando el subprotocolo de la URL coincide con el suyo propio — por eso es el subprotocolo, no el host, lo que enruta la solicitud.
Un ejemplo práctico: inspeccionando el registro de controladores
Este programa lista los controladores que conoce DriverManager, luego le pide que se conecte a tres URL de distintos proveedores — lo que permite observar el contrato de coincidencia de URL en acción.
Qué se puede extraer de la ejecución:
DriverManager.getDrivers()devuelve los controladores registrados como unEnumeration. En un entorno de ejecución sin JARs de controladores la lista está vacía — agregapostgresql.jaral classpath y elDriverde PostgreSQL aparecerá aquí automáticamente, sin ninguna llamada aClass.forName.- El subprotocolo de la URL (la parte después de
jdbc:—postgresql,mysql,h2) es con lo que cada controlador hace la coincidencia. Así es como una llamada agetConnectionse enruta al proveedor correcto: el controlador reclama su propio subprotocolo. - Cada URL falló de la misma manera aquí porque no hay ningún controlador presente. En un despliegue real, exactamente un controlador reclamaría cada URL; si olvidas la dependencia verás precisamente este mensaje "No suitable driver found" — síntoma de JAR ausente, no de contraseña incorrecta.
- El registro es automático mediante
ServiceLoader, pero el JAR del controlador aún debe estar en el classpath. La lección: un error "No suitable driver" es un problema de compilación/dependencia, que se resuelve enpom.xml, no en tu código Java. DriverexponegetMajorVersion/getMinorVersion, por lo que puedes registrar exactamente qué versión del controlador está en ejecución — útil cuando un error depende de la versión del controlador, no de tu código.
Una vez que un controlador está en el classpath y getConnection devuelve una Connection activa, el siguiente paso es ejecutar SQL a través de ella — consulta Conexión JDBC en Java y Sentencias JDBC en Java.