Introduzione a Java JDBC
Cos'è JDBC, come astrae l'accesso ai database in Java e l'architettura dell'API JDBC.
JDBC (Java Database Connectivity) è l'API standard per comunicare con un database relazionale da Java. Risiede nei package java.sql e javax.sql e fornisce un modo vendor-neutral per aprire una connessione, inviare SQL e leggere i risultati — che il database sottostante sia PostgreSQL, MySQL, Oracle, SQL Server o un motore embedded come H2. Impara l'API una volta sola e solo l'URL di connessione cambia quando passi a un altro database.
L'idea principale: uno strato sottile e uniforme su molti database
Il tuo codice è scritto contro le interfacce — Connection, Statement, ResultSet. Le classi concrete che le implementano sono distribuite in un driver JAR del fornitore. Il compito di JDBC è mantenere il tuo codice sul lato delle interfacce di quella linea, così cambiare database diventa una modifica alla configurazione, non una riscrittura.
I tipi fondamentali
Un gruppo ristretto di interfacce compare in quasi ogni programma JDBC:
| Interfaccia | Ruolo |
|---|---|
DriverManager | Trova un driver per il tuo URL e restituisce una Connection |
Connection | Una sessione attiva con il database; la factory per le statement |
Statement | Invia una stringa SQL fissa |
PreparedStatement | Invia un template SQL parametrizzato (il default sicuro) |
CallableStatement | Invoca una stored procedure |
ResultSet | Un cursore sulle righe restituite da una query |
SQLException | L'eccezione checked che ogni chiamata JDBC può lanciare |
La struttura di ogni programma JDBC
Quasi tutti gli accessi ai dati seguono gli stessi cinque passaggi. Ecco come appare con un database reale, usando try-with-resources affinché ogni risorsa si chiuda da sola:
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"));
}
}
}Ovvero: (1) identifica un database con un URL, (2) apri una Connection, (3) crea una statement, (4) eseguila, (5) leggi il ResultSet — poi chiudi tutto in ordine inverso. Il resto di questa parte espande ciascun passaggio.
Un sistema di tipi vendor-neutral
Le colonne SQL non sono tipi Java. JDBC fa da ponte tra i due con le costanti java.sql.Types — VARCHAR, INTEGER, TIMESTAMP, e così via — e un set parallelo di metodi getXxx/setXxx. Di solito non devi combattere questa mappatura, ma è il motivo per cui una colonna DATE viene serializzata in java.sql.Date e un NUMERIC in BigDecimal.
Un esempio pratico: la porta d'ingresso, senza driver installato
Questo programma non si connette a nulla — ispeziona il meccanismo JDBC stesso. Chiede a DriverManager quali driver sono registrati, mostra il contratto esatto che ottieni quando nessuno corrisponde a un URL, e stampa alcune delle costanti di tipo su cui è costruita l'API.
Cosa ricavare dall'esecuzione:
getConnectionè il singolo punto d'ingresso, mediato daDriverManager. Non si fa mainewdi una connessione — si identifica un database con un URL e JDBC instrada la richiesta. Il runtime qui non ha driver registrati, quindi il conteggio è0.- Quando nessun driver rivendica l'URL, JDBC non restituisce
nullné si blocca — lanciaSQLExceptioncon il messaggio 'No suitable driver found'. Ogni metodo JDBC segnala il fallimento in questo modo, motivo per cuiSQLExceptionè checked e la gestisci ovunque. - L'eccezione portava un SQLState (
08001, la classe standard 'client unable to establish connection'). I codici SQLState sono portabili tra i vendor, a differenza dei codici di errore interi, che sono specifici del vendor. - Le costanti
java.sql.Typessono sempliciint(VARCHARè 12,INTEGERè 4). Sono il modo in cui l'API denomina i tipi SQL indipendentemente da qualsiasi database specifico, e le passerai asetNulleregisterOutParameternei capitoli successivi. - Nulla qui richiedeva un database. L'API JDBC fa parte del JDK; solo il driver è esterno. Questa separazione è l'intera filosofia di progetto — il tuo codice compila e ragiona sui tipi
java.sqlsenza alcun database in vista.
Quando usare JDBC
JDBC è la fondamenta su cui si appoggiano tutti gli strumenti Java di livello superiore per i dati. Gli ORM come Hibernate o JPA, i query builder come jOOQ, e gli helper leggeri come JdbcTemplate di Spring chiamano tutti JDBC internamente. Usa JDBC direttamente quando vuoi pieno controllo sull'SQL, un footprint minimo di dipendenze, o stai imparando come funziona realmente il layer. Usa un ORM quando preferisci mappare le righe su oggetti e saltare il boilerplate. In entrambi i casi, i concetti in questa parte — connessioni, statement, result set e transazioni — sono ciò che quegli strumenti gestiscono per te.
Cosa tratta il resto di questa parte
Caricamento e scelta dei driver, apertura e configurazione di una Connection, i tre tipi di statement (Statement, PreparedStatement e CallableStatement), e navigazione di un ResultSet, oltre a transazioni, aggiornamenti batch e lettura dei metadati del database. Il prossimo capitolo parte da dove inizia ogni connessione: il driver.