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 exceptionLeaking 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.
What to take from the run:
- The URL is not opaque — it is structured data.
getConnectionparses 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 thePropertiesbag — both reach the driver, and you mix them to taste. - Credentials belong in
Properties(or theDataSourceconfig), not hard-coded in the URL string you log. The example masks the password on output for exactly that reason — never log credentials. connectTimeoutis 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
getConnectionis pure string work. The expensive part — the socket and server session — only happens at thegetConnectioncall itself, which is why you defer it and close it fast.
Practice
Why should a JDBC Connection almost always be acquired inside a try-with-resources statement?