W3docs

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

InterfacciaRuolo
DriverManagerTrova un driver per il tuo URL e restituisce una Connection
ConnectionUna sessione attiva con il database; la factory per le statement
StatementInvia una stringa SQL fissa
PreparedStatementInvia un template SQL parametrizzato (il default sicuro)
CallableStatementInvoca una stored procedure
ResultSetUn cursore sulle righe restituite da una query
SQLExceptionL'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.TypesVARCHAR, 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.

java— editable, runs on the server

Cosa ricavare dall'esecuzione:

  • getConnection è il singolo punto d'ingresso, mediato da DriverManager. Non si fa mai new di 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 null né si blocca — lancia SQLException con il messaggio 'No suitable driver found'. Ogni metodo JDBC segnala il fallimento in questo modo, motivo per cui SQLException è 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.Types sono semplici int (VARCHAR è 12, INTEGER è 4). Sono il modo in cui l'API denomina i tipi SQL indipendentemente da qualsiasi database specifico, e le passerai a setNull e registerOutParameter nei 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.sql senza 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.

Esercitazione

Pratica
In un tipico programma JDBC, perché il codice dell'applicazione è scritto contro interfacce come Connection e ResultSet piuttosto che classi concrete?
In un tipico programma JDBC, perché il codice dell'applicazione è scritto contro interfacce come Connection e ResultSet piuttosto che classi concrete?
Was this page helpful?