W3docs

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 interfacesConnection, 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:

InterfazFunción
DriverManagerEncuentra un controlador para su URL y devuelve una Connection
ConnectionUna sesión activa con la base de datos; la fábrica de statements
StatementEnvía una cadena SQL fija
PreparedStatementEnvía una plantilla SQL parametrizada (la opción segura por defecto)
CallableStatementInvoca un procedimiento almacenado
ResultSetUn cursor sobre las filas que devolvió una consulta
SQLExceptionLa 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.TypesVARCHAR, 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.

java— editable, runs on the server

Qué llevarse de la ejecución:

  • getConnection es el único punto de entrada, y está mediado por el DriverManager. Nunca hace new sobre 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 es 0.
  • Cuando ningún controlador reclama la URL, JDBC no devuelve null ni se queda colgado — lanza una SQLException con el mensaje «No suitable driver found». Cada método JDBC señala el fallo de esta manera, por lo que SQLException es 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.Types son simples int (VARCHAR es 12, INTEGER es 4). Así es como la API nombra los tipos SQL con independencia de cualquier base de datos concreta, y los pasará a setNull y registerOutParameter en 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.sql sin 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

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?