W3docs

Java JDBC Drivers

JDBC driver types, loading drivers in modern Java, and using DriverManager and DataSource to obtain connections.

Java JDBC Drivers

A JDBC driver is the vendor-supplied library that turns generic java.sql calls into the specific network protocol a database understands. The JDBC API is part of the JDK; the driver is an external JAR you add to the classpath. No driver, no connection — as the previous chapter's run showed.

The four driver types

The JDBC spec defines four historical driver types. In modern practice you almost always use Type 4:

TypeNameNotes
1JDBC-ODBC bridgeObsolete; removed from the JDK in Java 8
2Native-APIWraps a C client library; needs native code installed
3Network protocolTalks to middleware that talks to the database
4Pure-Java (thin)A single JAR, all Java, talks the DB wire protocol directly

Type 4 drivers — org.postgresql.Driver, com.mysql.cj.jdbc.Driver, the H2 driver — are just a JAR on the classpath. That is what you add to pom.xml or build.gradle.

Loading a driver: you usually do nothing

Old tutorials show Class.forName("com.mysql.cj.jdbc.Driver"). Since JDBC 4.0 (Java 6) that line is unnecessary. Drivers ship a META-INF/services/java.sql.Driver file, and DriverManager auto-registers them via the ServiceLoader mechanism the first time you call getConnection. So the modern code is simply:

// No Class.forName needed — the driver JAR self-registers.
Connection conn = DriverManager.getConnection(
    "jdbc:postgresql://localhost:5432/shop", "app", "secret");

DriverManager vs. DataSource

Two ways to obtain a connection:

  • DriverManager.getConnection(url, user, password) — simplest; good for tools, scripts, and demos. Opens a brand-new physical connection each call.
  • DataSource — the preferred approach for applications and servers. A DataSource (usually backed by a connection pool like HikariCP) hands out pooled connections, so close() returns the connection to the pool instead of tearing down a 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 */ }

How DriverManager picks a driver

When you call getConnection, DriverManager walks its list of registered drivers and asks each one "do you recognise this URL?" via Driver.acceptsURL. The first that says yes is used; if none do, you get "No suitable driver found".

A worked example: inspecting the driver registry

This program lists the drivers DriverManager knows about, then asks it to connect to three different vendor URLs — letting you watch the URL-matching contract in action.

java— editable, runs on the server

What to take from the run:

  • DriverManager.getDrivers() returns the registered drivers as an Enumeration. On a runtime with no driver JARs the list is empty — add postgresql.jar to the classpath and the PostgreSQL Driver would appear here automatically, with no Class.forName call.
  • The URL's subprotocol (the part after jdbc:postgresql, mysql, h2) is what each driver matches on. That is how one getConnection call routes to the right vendor: the driver claims its own subprotocol.
  • Every URL failed the same way here because no driver is present. In a real deployment, exactly one driver would claim each URL; if you forget the dependency you see precisely this "No suitable driver found" message — a missing-JAR symptom, not a bad-password one.
  • Registration is automatic via ServiceLoader, but the driver JAR must still be on the classpath. The lesson: a "No suitable driver" error is a build/dependency problem, fixed in pom.xml, not in your Java code.
  • Driver exposes getMajorVersion/getMinorVersion, so you can log exactly which driver build is running — useful when a bug depends on the driver version, not your code.

Practice

Practice

A teammate's modern (Java 17) application throws 'No suitable driver found for jdbc:postgresql://...' at startup. What is the most likely fix?