Driver JDBC in Java
Tipi di driver JDBC, caricamento in Java moderno e uso di DriverManager e DataSource per ottenere connessioni al database.
Un driver JDBC è la libreria fornita dal vendor che trasforma le chiamate generiche java.sql nel protocollo di rete specifico compreso dal database. L'API JDBC fa parte del JDK; il driver è un JAR esterno da aggiungere al classpath. Senza driver, nessuna connessione.
Questo capitolo tratta i quattro tipi di driver (e perché oggi ne conta solo uno), come Java moderno carica automaticamente i driver senza Class.forName, la differenza tra DriverManager e DataSource, e come DriverManager decide quale driver gestisce un dato URL. Per una visione d'insieme di come l'API JDBC si integra nel sistema, vedi Java JDBC Introduction; per agire su una connessione attiva una volta ottenuta, vedi Java JDBC Connection.
I quattro tipi di driver
La specifica JDBC definisce quattro tipi storici di driver. Nella pratica moderna si usa quasi sempre il Tipo 4:
| Tipo | Nome | Note |
|---|---|---|
| 1 | Bridge JDBC-ODBC | Obsoleto; rimosso dal JDK in Java 8 |
| 2 | Native-API | Racchiude una libreria client C; richiede codice nativo installato |
| 3 | Network protocol | Comunica con un middleware che parla con il database |
| 4 | Pure-Java (thin) | Un singolo JAR, tutto Java, parla direttamente il protocollo wire del DB |
I driver di Tipo 4 — org.postgresql.Driver, com.mysql.cj.jdbc.Driver, il driver H2 — sono semplicemente un JAR nel classpath. È quello che aggiungi a pom.xml o build.gradle. Poiché sono puro Java, girano su qualsiasi piattaforma supportata dalla JVM, senza nulla da installare sulla macchina host. Tratta i tipi più vecchi come storici: li vedrai in vecchia documentazione e domande d'esame, ma non li userai nel codice nuovo.
Caricare un driver: di solito non fai nulla
I vecchi tutorial mostrano Class.forName("com.mysql.cj.jdbc.Driver"). Da JDBC 4.0 (Java 6) quella riga è inutile. I driver includono un file META-INF/services/java.sql.Driver e DriverManager li registra automaticamente tramite il meccanismo ServiceLoader la prima volta che chiami getConnection. Il codice moderno è quindi semplicemente:
// No Class.forName needed — the driver JAR self-registers.
Connection conn = DriverManager.getConnection(
"jdbc:postgresql://localhost:5432/shop", "app", "secret");DriverManager vs. DataSource
Due modi per ottenere una connessione:
DriverManager.getConnection(url, user, password)— il più semplice; adatto per strumenti, script e demo. Apre una connessione fisica nuova a ogni chiamata.DataSource— l'approccio preferito per applicazioni e server. UnDataSource(di solito supportato da un connection pool come HikariCP) fornisce connessioni in pool, quindiclose()restituisce la connessione al pool invece di chiudere un socket.
HikariDataSource ds = new HikariDataSource();
ds.setJdbcUrl("jdbc:postgresql://localhost:5432/shop");
ds.setUsername("app");
ds.setPassword("secret");
try (Connection conn = ds.getConnection()) { /* borrowed from the pool */ }L'URL JDBC
Ogni connessione inizia con un URL JDBC, che ha sempre la forma jdbc:<subprotocol>:<subname>:
jdbc:postgresql://localhost:5432/shop
│ │ │
│ │ └─ subname: host, port, database, options
│ └───────────── subprotocol: identifies the vendor/driver
└────────────────── scheme: always "jdbc"Il subprotocol (postgresql, mysql, h2, oracle, sqlserver) è la parte che decide quale driver gestisce la richiesta. Ogni vendor documenta il proprio formato URL e le opzioni che seguono il nome del database (impostazioni TLS, fuso orario, flag di connessione), quindi controlla la documentazione del driver per la sintassi esatta.
Come DriverManager sceglie un driver
Quando chiami getConnection, DriverManager scorre la sua lista di driver registrati e chiede a ciascuno "riconosci questo URL?" tramite Driver.acceptsURL. Il primo che risponde sì viene usato; se nessuno lo fa, si ottiene No suitable driver found. Un driver risponde tipicamente "sì" solo quando il subprotocol dell'URL corrisponde al proprio — ecco perché è il subprotocol, non l'host, a instradare la richiesta.
Un esempio pratico: ispezione del registro dei driver
Questo programma elenca i driver che DriverManager conosce, poi gli chiede di connettersi a tre URL di vendor diversi — permettendoti di osservare in azione il contratto di corrispondenza URL.
Cosa ricavare dall'esecuzione:
DriverManager.getDrivers()restituisce i driver registrati comeEnumeration. Su un runtime senza JAR driver la lista è vuota — aggiungerepostgresql.jaral classpath farebbe comparire automaticamente ilDriverPostgreSQL, senza alcuna chiamata aClass.forName.- Il subprotocol dell'URL (la parte dopo
jdbc:—postgresql,mysql,h2) è ciò su cui ogni driver effettua la corrispondenza. È così che una chiamatagetConnectionviene instradata al vendor giusto: il driver rivendica il proprio subprotocol. - Ogni URL ha fallito allo stesso modo qui perché non è presente alcun driver. In un deployment reale, esattamente un driver rivendicherebbe ciascun URL; se dimentichi la dipendenza vedi esattamente questo messaggio "No suitable driver found" — un sintomo di JAR mancante, non di password errata.
- La registrazione è automatica tramite
ServiceLoader, ma il JAR del driver deve comunque essere nel classpath. La lezione: un errore "No suitable driver" è un problema di build/dipendenza, da correggere inpom.xml, non nel codice Java. DriveresponegetMajorVersion/getMinorVersion, quindi puoi registrare esattamente quale versione del driver è in esecuzione — utile quando un bug dipende dalla versione del driver, non dal tuo codice.
Una volta che un driver è nel classpath e getConnection restituisce una Connection attiva, il passo successivo è eseguire SQL attraverso di essa — vedi Java JDBC Connection e Java JDBC Statement.