La Arquitectura en Capas de JDBC
Tu código nunca habla con un motor de base de datos en particular: programa contra las interfaces de java.sql, y cada fabricante entrega el Driver que las implementa en binario.
jdbc:postgresql://localhost:5432/tienda 0 líneas cambiadas en la capa de aplicación Inyección SQL vs PreparedStatement: La Separación Estructural
Concatenar la entrada del usuario en el SQL confunde datos con código ejecutable. PreparedStatement compila la consulta como un árbol fijo antes de que el dato exista.
String sql = "SELECT * FROM usuarios "
+ "WHERE email = '" + entrada + "'";
rs = statement.executeQuery(sql); SELECT * FROM usuarios WHERE email = 'facundo@mail.com' String sql = "SELECT * FROM usuarios "
+ "WHERE email = ?";
ps = conn.prepareStatement(sql);
ps.setString(1, entrada); SELECT * FROM usuarios WHERE email = ? → "facundo@mail.com" El Cursor de ResultSet: Recorriendo Registros en Memoria
ResultSet no es una lista cargada en memoria: es un cursor que apunta a un buffer y dialoga con la base fila por fila mediante rs.next().
| id | nombre | precio |
|---|---|---|
| 1 | Teclado | 45.0 |
| 2 | Mouse | 20.0 |
| 3 | Monitor | 220.0 |
// todavía no se llamó a rs.next() Transacciones ACID: El Protocolo Atómico de Transferencia
Si una transferencia de $100 entre dos cuentas se interrumpe a mitad de camino, el dinero no puede evaporarse: o se confirman todos los cambios con commit, o no se aplica ninguno con rollback.
conn.setAutoCommit(false); Pools de Conexiones (HikariCP) y el Patrón DAO
Abrir una conexión TCP/TLS con autenticación cuesta cientos de milisegundos. Un pool como HikariCP mantiene conexiones ya abiertas listas para prestarse.
conn.close() no destruye la conexión: la devuelve al pool para el próximo request.