Clase Conexion - eliizquierdo/material_programacion_avanzada2026 GitHub Wiki
📦 Proyecto:
mini-crud-sql(Tema 3 — JDBC + MySQL) — ⬇️ Descargar ZIP · ☁️ Abrir en Codespace
Sin una clase Conexion, cada vez que un DAO necesita acceder a la base de datos tendría que repetir todo esto:
// ❌ Código repetitivo en CADA método del DAO
String url = "jdbc:mysql://localhost:3306/institutoWeb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC";
Connection con = DriverManager.getConnection(url, "root", "admin123");
// ... usar la conexión
con.close();Si la contraseña cambia, hay que buscar y cambiar en 10 lugares distintos.
Con la clase Conexion, cualquier DAO hace simplemente:
// ✅ Una sola línea
Connection con = Conexion.obtener();Ventajas:
- Los parámetros de conexión están en un solo lugar
- Las credenciales van en un archivo separado, no en el código Java
- El cierre de la conexión lo maneja
try-with-resourcesautomáticamente
La clase usa el patrón Static Factory Method: un método static que crea y devuelve objetos sin necesidad de usar new.
La palabra clave static permite llamar al método usando el nombre de la clase directamente:
Connection con = Conexion.obtener(); // sin new, sin instanciaLas credenciales van en un archivo de texto separado, no en el código Java. Esto es importante porque:
- Si alguien ve tu código en GitHub, no ve la contraseña
- Si cambia la contraseña, solo cambias el
.properties, no el.java
Ubicación: src/main/resources/db.properties
# Configuración de la base de datos
db.url=jdbc:mysql://localhost:3306/institutoWeb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
db.username=java_dev
db.password=java2026jdbc:mysql://localhost:3306/institutoWeb?useSSL=false&allowPublicKeyRetrieval=true&serverTimezone=UTC
└────┬───┘ └──────┬─────┘ └─────┬────┘ └─────────────────────────────┬────────────────────────────┘
Protocolo Servidor y puerto Base de datos Parámetros opcionales
| Parte | Descripción |
|---|---|
jdbc:mysql |
Protocolo para conectarse a MySQL desde Java |
localhost:3306 |
Servidor local, puerto 3306 (el de MySQL por defecto) |
/institutoWeb |
Nombre de la base de datos |
useSSL=false |
Desactiva SSL en entornos de desarrollo |
allowPublicKeyRetrieval=true |
Necesario en MySQL 8.x: sin esto, la conexión falla con "Public Key Retrieval is not allowed" al usar el método de autenticación por defecto |
serverTimezone=UTC |
Necesario en MySQL 8.x para evitar errores de zona horaria |
package modelo.conexion;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
/**
* Factoría estática de conexiones a la base de datos.
* Las credenciales se leen desde src/main/resources/db.properties.
*/
public class Conexion {
private static final String ARCHIVO = "db.properties";
// Registrar el driver JDBC explícitamente (evita "No suitable driver found" en Tomcat)
static {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
System.err.println("ERROR: No se encontró el driver de MySQL en el classpath.");
e.printStackTrace();
}
}
// Las propiedades se cargan UNA SOLA VEZ cuando arranca la aplicación
private static final Properties config = cargarPropiedades();
// ── Carga del archivo de propiedades ──────────────────────────────────
private static Properties cargarPropiedades() {
Properties props = new Properties();
try (InputStream input = Conexion.class
.getClassLoader()
.getResourceAsStream(ARCHIVO)) {
if (input == null) {
System.err.println("ERROR: No se encontró " + ARCHIVO);
return props;
}
props.load(input);
} catch (Exception e) {
System.err.println("ERROR al leer " + ARCHIVO);
e.printStackTrace();
}
return props;
}
// ── Método principal: devuelve una nueva conexión ─────────────────────
/**
* Devuelve una nueva conexión a la base de datos.
* Recuerda cerrarla con try-with-resources en el DAO.
*/
public static Connection obtener() throws SQLException {
String url = config.getProperty("db.url");
String usuario = config.getProperty("db.username");
String password = config.getProperty("db.password");
return DriverManager.getConnection(url, usuario, password);
}
}En teoría, desde JDBC 4.0 el DriverManager debería descubrir el driver de MySQL solo, sin necesidad de cargarlo a mano. En la práctica, dentro de Tomcat esto puede fallar con el error SQLException: No suitable driver found, aunque el .jar del driver esté correctamente en WEB-INF/lib.
Esto pasa porque Tomcat aísla el classloader de cada aplicación web, y el mecanismo automático de DriverManager a veces no llega a "ver" el driver cargado por ese classloader aislado. La solución es forzar la carga de la clase del driver con Class.forName(...) dentro de un bloque static — así se ejecuta una sola vez, apenas se carga la clase Conexion, y garantiza que el driver quede registrado antes de la primera conexión.
El DAO usa try-with-resources: Java cierra la conexión automáticamente al salir del bloque, aunque haya un error. No hace falta escribir un bloque finally.
// Ejemplo: listar todas las personas
public ArrayList<PersonaVO> getLista() {
ArrayList<PersonaVO> lista = new ArrayList<>();
String sql = "SELECT * FROM personas";
try (Connection con = Conexion.obtener();
PreparedStatement ps = con.prepareStatement(sql);
ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
lista.add(new PersonaVO(rs.getInt("codigo"), rs.getString("nombre")));
}
} catch (SQLException e) {
e.printStackTrace();
}
// ← con, ps y rs se cierran solos aquí (try-with-resources)
return lista;
}Sin pool de conexiones: cada llamada a obtener() abre una conexión nueva y la cierra. Para aplicaciones con muchos usuarios simultáneos, esto es lento (~100ms por conexión). La solución es usar HikariCP o Apache DBCP.
Credenciales en texto plano: el .properties sigue siendo texto legible. En producción, se usan variables de entorno o servicios de secretos.
Continuamos por la clase PersonaDAO → MODELO-PersonaDAO
Conexion · db.properties · Static Factory Method · Conexion.obtener() · try-with-resources · URL JDBC · jdbc:mysql · DriverManager · credenciales · useSSL · serverTimezone · cargarPropiedades · no hardcodear
🧠 Autoevaluación — Clase Conexion
← Introducción: BD + Web · 🏠 Inicio · Clase PersonaDAO actualizada →
