W3docs

Java JDBC Connection

Open and manage database connections in Java with the Connection interface — open, close, and configure.

Java JDBC Connection

A Connection is a live session with the database. It is the object you get back from DriverManager (or a DataSource), and it is the factory for everything else — statements, transactions, savepoints, metadata. A connection is also a scarce, expensive resource: every open one ties up a socket and a server-side session, so the cardinal rule is open late, close promptly.

The connection URL

Everything DriverManager needs to find and reach a database is encoded in the URL:

jdbc:<subprotocol>://<host>:<port>/<database>?<key=value&...>

For example jdbc:postgresql://db.internal:5432/shop?ssl=true. The jdbc: prefix is mandatory; the subprotocol selects the driver; the rest is vendor-specific but conventionally host, port, database, and a query string of tuning options.

Three ways to open one

// 1. URL with credentials as arguments
Connection a = DriverManager.getConnection(url, "app", "secret");

// 2. URL with a Properties bag (user, password, plus driver-specific keys)
Properties props = new Properties();
props.setProperty("user", "app");
props.setProperty("password", "secret");
props.setProperty("connectTimeout", "10");
Connection b = DriverManager.getConnection(url, props);

// 3. From a pooled DataSource (preferred for applications)
Connection c = dataSource.getConnection();

Always close it — use try-with-resources

Connection, Statement, and ResultSet all implement AutoCloseable. Declaring them in a try-with-resources header guarantees they close in reverse order even if an exception is thrown — the single most important habit in JDBC:

try (Connection conn = DriverManager.getConnection(url, "app", "secret")) {
  // use conn...
} // conn.close() runs here automatically, even on exception

Leaking connections (forgetting to close) exhausts the pool and eventually hangs the whole application — a classic production outage.

Configuring a connection

Once open, a connection carries session-level settings you will meet in later chapters: setAutoCommit(false) to begin a manual transaction, setTransactionIsolation(...) to pick an isolation level, setReadOnly(true) as a hint for read-only work, and setSchema(...) / setCatalog(...) to pick a namespace. isValid(timeout) checks the connection is still alive — pools use it to discard dead ones.

A worked example: the anatomy of a connection URL

This program takes a realistic JDBC URL apart into its components and builds the Properties bag you would pass alongside it — the two inputs getConnection needs — without requiring a live database.

java— editable, runs on the server

What to take from the run:

  • The URL is not opaque — it is structured data. getConnection parses exactly these pieces: the subprotocol picks the driver, and the host/port/database tell that driver where to connect. Reading a URL out loud is the fastest way to debug "wrong database" mistakes.
  • The query string (?ssl=true&applicationName=reports) carries driver-specific options. The same settings can travel in the URL or in the Properties bag — both reach the driver, and you mix them to taste.
  • Credentials belong in Properties (or the DataSource config), not hard-coded in the URL string you log. The example masks the password on output for exactly that reason — never log credentials.
  • connectTimeout is a real PostgreSQL driver property. Tuning lives in these key/value pairs, which is why you rarely subclass anything: configuration, not code, shapes a connection.
  • This ran with no database because building the inputs to getConnection is pure string work. The expensive part — the socket and server session — only happens at the getConnection call itself, which is why you defer it and close it fast.

Practice

Practice

Why should a JDBC Connection almost always be acquired inside a try-with-resources statement?