W3docs

Java JDBC Introduction

What JDBC is, how it abstracts database access in Java, and the architecture of the JDBC API.

JDBC (Java Database Connectivity) is the standard API for talking to a relational database from Java. It lives in the java.sql and javax.sql packages and gives you one vendor-neutral way to open a connection, send SQL, and read results — whether the database behind it is PostgreSQL, MySQL, Oracle, SQL Server, or an embedded engine like H2. Learn the API once and only the connection URL changes when you switch databases.

The big idea: a thin, uniform layer over many databases

Your code is written against interfacesConnection, Statement, ResultSet. The actual classes that implement them ship in a vendor driver JAR. JDBC's job is to keep your code on the interface side of that line so a database swap is a configuration change, not a rewrite.

The core types

A handful of interfaces appear in almost every JDBC program:

InterfaceRole
DriverManagerFinds a driver for your URL and hands back a Connection
ConnectionA live session with the database; the factory for statements
StatementSends a fixed SQL string
PreparedStatementSends a parameterized SQL template (the safe default)
CallableStatementInvokes a stored procedure
ResultSetA cursor over the rows a query returned
SQLExceptionThe checked exception every JDBC call can throw

The shape of every JDBC program

Almost all data access follows the same five steps. Here it is against a live database, using try-with-resources so every resource closes itself:

String url = "jdbc:postgresql://localhost:5432/shop";
String sql = "SELECT id, name FROM product WHERE price < ?";

try (Connection conn = DriverManager.getConnection(url, "app", "secret");
     PreparedStatement ps = conn.prepareStatement(sql)) {
  ps.setBigDecimal(1, new BigDecimal("9.99"));
  try (ResultSet rs = ps.executeQuery()) {
    while (rs.next()) {
      System.out.println(rs.getInt("id") + " " + rs.getString("name"));
    }
  }
}

That is: (1) name a database with a URL, (2) open a Connection, (3) create a statement, (4) execute it, (5) read the ResultSet — then close everything in reverse order. The rest of this part expands each step.

A vendor-neutral type system

SQL columns are not Java types. JDBC bridges the two with the java.sql.Types constants — VARCHAR, INTEGER, TIMESTAMP, and so on — and a parallel set of getXxx/setXxx methods. You rarely fight this mapping, but it is the reason a DATE column round-trips to java.sql.Date and a NUMERIC to BigDecimal.

A worked example: the front door, with no driver installed

This program does not connect to anything — it inspects the JDBC machinery itself. It asks DriverManager which drivers are registered, shows the exact contract you get when none matches a URL, and prints a few of the type constants the API is built on.

java— editable, runs on the server

What to take from the run:

  • getConnection is the single entry point, and it is mediated by DriverManager. You never new a connection — you name a database with a URL and JDBC routes the request. The runtime here has no driver registered, so the count is 0.
  • When no driver claims the URL, JDBC does not return null or hang — it throws SQLException with the message 'No suitable driver found'. Every JDBC method signals failure this way, which is why SQLException is checked and you handle it everywhere.
  • The exception carried a SQLState (08001, the standard 'client unable to establish connection' class). SQLState codes are portable across vendors, unlike the integer error codes, which are vendor-specific.
  • The java.sql.Types constants are plain ints (VARCHAR is 12, INTEGER is 4). They are how the API names SQL types independently of any one database, and you will pass them to setNull and registerOutParameter in later chapters.
  • Nothing here needed a database. The JDBC API is part of the JDK; only the driver is external. That separation is the whole design — your code compiles and reasons about java.sql types with no database in sight.

When to reach for JDBC

JDBC is the foundation that every higher-level Java data tool sits on. Object-relational mappers like Hibernate or JPA, query builders like jOOQ, and lighter helpers like Spring's JdbcTemplate all call JDBC under the hood. Reach for raw JDBC directly when you want full control over the SQL, a minimal dependency footprint, or you are learning how the layer actually works. Reach for an ORM when you would rather map rows to objects and skip the boilerplate. Either way, the concepts in this part — connections, statements, result sets, and transactions — are what those tools manage for you.

What the rest of this part covers

Loading and choosing drivers, opening and configuring a Connection, the three statement kinds (Statement, PreparedStatement, and CallableStatement), and navigating a ResultSet, plus transactions, batch updates, and reading database metadata. The next chapter starts where every connection begins: the driver.

Practice

Practice
In a typical JDBC program, why is your application code written against interfaces like Connection and ResultSet rather than concrete classes?
In a typical JDBC program, why is your application code written against interfaces like Connection and ResultSet rather than concrete classes?
Was this page helpful?