04 - JDBC

JDBC (*Java Database Connectivity*) es la API estándar de Java para conectarse a bases de datos y ejecutar SQL. Cada motor (MariaDB, PostgreSQL…) proporciona un driver que la implementa.

La configuración se externaliza en un fichero de propiedades, no en el código:

db.url=jdbc:mariadb://localhost:3306/library
db.user=library_user
db.password=secret

public final class DbConnection {
    private static final Properties PROPERTIES = loadProperties();

    public static Connection get() throws SQLException {
        return DriverManager.getConnection(
                PROPERTIES.getProperty("db.url"),
                PROPERTIES.getProperty("db.user"),
                PROPERTIES.getProperty("db.password"));
    }
}

DriverManager.getConnection abre una conexión con el driver del classpath.

String sql = "SELECT id, title, price FROM book WHERE publisher_id = ?";

try (Connection connection = DbConnection.get();
     PreparedStatement statement = connection.prepareStatement(sql)) {

    statement.setLong(1, publisherId);

    try (ResultSet resultSet = statement.executeQuery()) {
        while (resultSet.next()) {
            long id = resultSet.getLong("id");
            String title = resultSet.getString("title");
            BigDecimal price = resultSet.getBigDecimal("price");
        }
    }
}

  • El marcador ? se sustituye con setLong, setString…
  • El parametrizado evita la inyección SQL: el valor nunca se interpreta como parte de la sentencia. Concatenar SQL con datos del usuario es un error grave.
  • try-with-resources cierra Connection, PreparedStatement y ResultSet aunque ocurra una excepción.
Método Uso
executeQuery() SELECT; devuelve ResultSet
executeUpdate() INSERT/UPDATE/DELETE; devuelve filas afectadas
execute() Sentencias generales

Para recuperar el id generado por un INSERT:

try (PreparedStatement statement = connection.prepareStatement(sql,
        Statement.RETURN_GENERATED_KEYS)) {
    statement.setString(1, book.title());
    statement.executeUpdate();
    try (ResultSet keys = statement.getGeneratedKeys()) {
        if (keys.next()) {
            long id = keys.getLong(1);
        }
    }
}

Por defecto cada sentencia se confirma al ejecutarse (autocommit). Cuando varias operaciones deben ser atómicas — todas o ninguna — se desactiva y se gestiona explícitamente:

Connection connection = DbConnection.get();
try {
    connection.setAutoCommit(false);
    // insertar pedido, actualizar stock...
    connection.commit();
} catch (SQLException exception) {
    connection.rollback();
    throw exception;
} finally {
    connection.setAutoCommit(true);
    connection.close();
}

Si algo falla a mitad de camino, rollback() deshace todo lo pendiente.

SQLException informa del problema: getErrorCode() y getSQLState() permiten distinguir, por ejemplo, una violación de clave única de un fallo de conexión. En la capa de persistencia se traduce a excepciones propias de la aplicación.

Una conexión abre y cierra por operación o por bloque lógico. Las conexiones son un recurso del servidor: mantenerlas abiertas innecesariamente agota la base de datos.
  • clase/daw/bbdd/1eval/jdbc.txt
  • Última modificación: 2026/10/12 12:51
  • por cesguiro