Introducción a Java JDBC
Qué es JDBC, cómo abstrae el acceso a bases de datos en Java y la arquitectura de la API JDBC.
Introducción a Java JDBC
JDBC (Java Database Connectivity) es la API estándar para hablar con una base de datos relacional desde Java. Reside en los paquetes java.sql y javax.sql y le ofrece una única forma independiente del proveedor de abrir una conexión, enviar SQL y leer resultados — ya sea que la base de datos detrás sea PostgreSQL, MySQL, Oracle, SQL Server o un motor embebido como H2. Aprenda la API una vez, y solo la URL de conexión cambia cuando cambia de base de datos.
La gran idea: una capa fina y uniforme sobre muchas bases de datos
Su código se escribe contra interfaces — Connection, Statement, ResultSet. Las clases concretas que las implementan se distribuyen en un JAR de controlador del proveedor. La tarea de JDBC es mantener su código del lado de la interfaz de esa frontera, de modo que un cambio de base de datos sea una modificación de configuración y no una reescritura.
Los tipos fundamentales
Un puñado de interfaces aparece en casi todos los programas JDBC:
| Interfaz | Función |
|---|---|
DriverManager | Encuentra un controlador para su URL y devuelve una Connection |
Connection | Una sesión activa con la base de datos; la fábrica de statements |
Statement | Envía una cadena SQL fija |
PreparedStatement | Envía una plantilla SQL parametrizada (la opción segura por defecto) |
CallableStatement | Invoca un procedimiento almacenado |
ResultSet | Un cursor sobre las filas que devolvió una consulta |
SQLException | La excepción comprobada que puede lanzar cualquier llamada JDBC |
La forma de todo programa JDBC
Casi todo el acceso a datos sigue los mismos cinco pasos. Aquí están frente a una base de datos activa, usando try-with-resources para que cada recurso se cierre solo:
String url = "jdbc:postgresql://localhost:5432/shop";
String sql = "SELECT id, name FROM product WHERE price < ?";
try (Connection conn = DriverManager.getConnection(url, "app", "secret");
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setBigDecimal(1, new BigDecimal("9.99"));
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
System.out.println(rs.getInt("id") + " " + rs.getString("name"));
}
}
}Es decir: (1) nombrar una base de datos con una URL, (2) abrir una Connection, (3) crear un statement, (4) ejecutarlo, (5) leer el ResultSet — y luego cerrar todo en orden inverso. El resto de esta parte amplía cada paso.
Un sistema de tipos independiente del proveedor
Las columnas SQL no son tipos Java. JDBC tiende un puente entre ambos con las constantes java.sql.Types — VARCHAR, INTEGER, TIMESTAMP, etc. — y un conjunto paralelo de métodos getXxx/setXxx. Rara vez peleará contra este mapeo, pero es la razón por la que una columna DATE va y vuelve a java.sql.Date y una NUMERIC a BigDecimal.
Un ejemplo trabajado: la puerta principal, sin controlador instalado
Este programa no se conecta a nada — inspecciona la propia maquinaria de JDBC. Le pregunta al DriverManager qué controladores están registrados, muestra el contrato exacto que se obtiene cuando ninguno coincide con una URL, e imprime algunas de las constantes de tipo sobre las que se construye la API.
Qué llevarse de la ejecución:
getConnectiones el único punto de entrada, y está mediado por elDriverManager. Nunca hacenewsobre una conexión — nombra una base de datos con una URL y JDBC encamina la solicitud. El entorno de ejecución aquí no tiene ningún controlador registrado, por lo que el recuento es0.- Cuando ningún controlador reclama la URL, JDBC no devuelve
nullni se queda colgado — lanza unaSQLExceptioncon el mensaje «No suitable driver found». Cada método JDBC señala el fallo de esta manera, por lo queSQLExceptiones comprobada y la maneja en todas partes. - La excepción llevaba un SQLState (
08001, la clase estándar «client unable to establish connection»). Los códigos SQLState son portables entre proveedores, a diferencia de los códigos de error enteros, que son específicos del proveedor. - Las constantes
java.sql.Typesson simplesint(VARCHARes 12,INTEGERes 4). Así es como la API nombra los tipos SQL con independencia de cualquier base de datos concreta, y los pasará asetNullyregisterOutParameteren capítulos posteriores. - Nada de esto necesitó una base de datos. La API JDBC es parte del JDK; solo el controlador es externo. Esa separación es todo el diseño — su código compila y razona sobre los tipos
java.sqlsin ninguna base de datos a la vista.
Qué cubre el resto de esta parte
Cargar y elegir controladores, abrir y configurar una Connection, las tres clases de statements, navegar por un ResultSet, las transacciones, las actualizaciones por lotes y la lectura de metadatos de la base de datos. El siguiente capítulo empieza donde empieza toda conexión: el controlador.
Práctica
En un programa JDBC típico, ¿por qué el código de su aplicación se escribe contra interfaces como Connection y ResultSet en lugar de clases concretas?