Java JDBC-Treiber
JDBC-Treibertypen, Laden von Treibern in modernem Java sowie Verwendung von DriverManager und DataSource zum Aufbau von Verbindungen.
Ein JDBC-Treiber ist die vom Hersteller gelieferte Bibliothek, die generische java.sql-Aufrufe in das spezifische Netzwerkprotokoll umwandelt, das eine Datenbank versteht. Die JDBC API ist Teil des JDK; der Treiber ist ein externes JAR, das Sie dem Classpath hinzufügen. Kein Treiber, keine Verbindung.
Dieses Kapitel behandelt die vier Treibertypen (und warum heute nur einer relevant ist), wie modernes Java Treiber automatisch lädt ohne Class.forName, den Unterschied zwischen DriverManager und DataSource sowie wie DriverManager entscheidet, welcher Treiber eine bestimmte URL verarbeitet. Einen Überblick darüber, wie die JDBC API zusammenarbeitet, finden Sie unter Java JDBC Introduction; um mit einer aktiven Verbindung zu arbeiten, sobald Sie eine haben, lesen Sie Java JDBC Connection.
Die vier Treibertypen
Die JDBC-Spezifikation definiert vier historische Treibertypen. In der modernen Praxis verwenden Sie fast immer Typ 4:
| Typ | Name | Hinweise |
|---|---|---|
| 1 | JDBC-ODBC-Brücke | Veraltet; aus dem JDK in Java 8 entfernt |
| 2 | Native-API | Umhüllt eine C-Clientbibliothek; benötigt installierten nativen Code |
| 3 | Netzwerkprotokoll | Kommuniziert mit Middleware, die mit der Datenbank kommuniziert |
| 4 | Pure-Java (thin) | Ein einzelnes JAR, reines Java, kommuniziert direkt über das DB-Wire-Protokoll |
Typ-4-Treiber — org.postgresql.Driver, com.mysql.cj.jdbc.Driver, der H2-Treiber — sind lediglich ein JAR im Classpath. Das ist es, was Sie zu pom.xml oder build.gradle hinzufügen. Da sie reines Java sind, laufen sie auf jeder Plattform, auf der die JVM läuft, ohne dass auf dem Host-Rechner etwas installiert werden muss. Behandeln Sie die älteren Typen als historisch: Sie werden sie in alten Dokumentationen und Prüfungsfragen sehen, aber Sie werden sie nicht in neuem Code verwenden.
Einen Treiber laden: Meistens müssen Sie nichts tun
Alte Anleitungen zeigen Class.forName("com.mysql.cj.jdbc.Driver"). Seit JDBC 4.0 (Java 6) ist diese Zeile nicht mehr notwendig. Treiber liefern eine META-INF/services/java.sql.Driver-Datei mit, und DriverManager registriert sie automatisch über den ServiceLoader-Mechanismus beim ersten Aufruf von getConnection. Der moderne Code lautet daher einfach:
// No Class.forName needed — the driver JAR self-registers.
Connection conn = DriverManager.getConnection(
"jdbc:postgresql://localhost:5432/shop", "app", "secret");DriverManager vs. DataSource
Zwei Wege, um eine Verbindung zu erhalten:
DriverManager.getConnection(url, user, password)— am einfachsten; gut für Tools, Skripte und Demos. Öffnet bei jedem Aufruf eine brandneue physische Verbindung.DataSource— der bevorzugte Ansatz für Anwendungen und Server. EinDataSource(üblicherweise durch einen Verbindungspool wie HikariCP unterstützt) gibt gepoolte Verbindungen heraus, sodassclose()die Verbindung an den Pool zurückgibt, anstatt einen Socket zu schließen.
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 */ }Die JDBC URL
Jede Verbindung beginnt mit einer JDBC URL, die immer die Form jdbc:<subprotocol>:<subname> hat:
jdbc:postgresql://localhost:5432/shop
│ │ │
│ │ └─ subname: host, port, database, options
│ └───────────── subprotocol: identifies the vendor/driver
└────────────────── scheme: always "jdbc"Das Subprotokoll (postgresql, mysql, h2, oracle, sqlserver) ist der Teil, der entscheidet, welcher Treiber die Anfrage verarbeitet. Jeder Hersteller dokumentiert sein eigenes URL-Format und die Optionen, die dem Datenbanknamen folgen (TLS-Einstellungen, Zeitzone, Verbindungsflags); prüfen Sie daher die Dokumentation des Treibers für die genaue Syntax.
Wie DriverManager einen Treiber auswählt
Wenn Sie getConnection aufrufen, durchläuft DriverManager seine Liste der registrierten Treiber und fragt jeden: "Erkennen Sie diese URL?" über Driver.acceptsURL. Der Erste, der mit Ja antwortet, wird verwendet; antwortet keiner, erhalten Sie No suitable driver found. Ein Treiber antwortet in der Regel mit "Ja" nur, wenn das Subprotokoll der URL seinem eigenen entspricht — weshalb das Subprotokoll, nicht der Host, die Anfrage weiterleitet.
Ein praktisches Beispiel: Die Treiberregistrierung untersuchen
Dieses Programm listet die Treiber auf, die DriverManager kennt, und fordert es dann auf, sich mit drei verschiedenen Hersteller-URLs zu verbinden — damit Sie den URL-Matching-Mechanismus in Aktion beobachten können.
Was aus der Ausführung zu entnehmen ist:
DriverManager.getDrivers()gibt die registrierten Treiber alsEnumerationzurück. Auf einer Laufzeitumgebung ohne Treiber-JARs ist die Liste leer — fügen Siepostgresql.jardem Classpath hinzu, und der PostgreSQL-Driverwürde hier automatisch erscheinen, ohne einenClass.forName-Aufruf.- Das Subprotokoll der URL (der Teil nach
jdbc:—postgresql,mysql,h2) ist das, worauf jeder Treiber prüft. So leitet eingetConnection-Aufruf zum richtigen Hersteller weiter: Der Treiber beansprucht sein eigenes Subprotokoll. - Jede URL ist hier auf dieselbe Weise fehlgeschlagen, weil kein Treiber vorhanden ist. In einem echten Deployment würde genau ein Treiber jede URL beanspruchen; wenn Sie die Abhängigkeit vergessen, sehen Sie genau diese Meldung "No suitable driver found" — ein Symptom für ein fehlendes JAR, nicht für ein falsches Passwort.
- Die Registrierung erfolgt automatisch über
ServiceLoader, aber das Treiber-JAR muss sich trotzdem im Classpath befinden. Die Lektion: Ein "No suitable driver"-Fehler ist ein Build-/Abhängigkeitsproblem, das inpom.xmlbehoben wird, nicht in Ihrem Java-Code. DriverstelltgetMajorVersion/getMinorVersionbereit, sodass Sie genau protokollieren können, welcher Treiber-Build ausgeführt wird — nützlich, wenn ein Fehler von der Treiberversion abhängt, nicht von Ihrem Code.
Sobald ein Treiber im Classpath ist und getConnection eine aktive Connection zurückgibt, ist der nächste Schritt die Ausführung von SQL darüber — siehe Java JDBC Connection und Java JDBC Statement.