JDBC: Connecting Java to a Database
JDBC (Java Database Connectivity) is the standard API for talking to relational databases from Java. With JDBC you open a Connection, send SQL through a Statement or — far safer — a PreparedStatement, and read query results from a ResultSet. The same code works across databases (MySQL, PostgreSQL, SQLite, and more) because each provides a JDBC driver that plugs in behind the standard interfaces.
What you need
- A running database and its connection URL.
- The JDBC driver for that database on your classpath (usually a single
.jaryou add via Maven or Gradle). - JDBC itself, which is part of the standard
java.sqlpackage.
Opening a connection
A JDBC URL has the form jdbc:<database>://host:port/dbname. Always close connections — try-with-resources does this for you.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
String url = "jdbc:mysql://localhost:3306/school";
String user = "appuser";
String password = "secret"; // in real apps, load from config, never hard-code
// try-with-resources closes the connection automatically.
try (Connection conn = DriverManager.getConnection(url, user, password)) {
System.out.println("Connected!");
} catch (SQLException e) {
System.out.println("Connection failed: " + e.getMessage());
}
Querying with PreparedStatement
Use PreparedStatement with ? placeholders rather than building SQL by string concatenation. This is both safer (it prevents SQL injection) and often faster.
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
String sql = "SELECT name, marks FROM students WHERE marks >= ?";
try (Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement ps = conn.prepareStatement(sql)) {
ps.setInt(1, 40); // bind 40 to the first placeholder, safely
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) { // advance row by row
String name = rs.getString("name");
int marks = rs.getInt("marks");
System.out.println(name + ": " + marks);
}
}
}
executeQuery() runs a SELECT and returns a ResultSet you walk with next(). Column values are read by name or index.
Want to learn this properly?
Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.
Browse coursesInserting and updating
For statements that change data (INSERT, UPDATE, DELETE), use executeUpdate(), which returns the number of affected rows.
String insert = "INSERT INTO students (name, marks) VALUES (?, ?)";
try (Connection conn = DriverManager.getConnection(url, user, password);
PreparedStatement ps = conn.prepareStatement(insert)) {
ps.setString(1, "Asha");
ps.setInt(2, 72);
int rows = ps.executeUpdate(); // returns 1 if one row inserted
System.out.println("Inserted " + rows + " row(s)");
}
Why never concatenate SQL
Building a query like "... WHERE name = '" + userInput + "'" invites SQL injection — a malicious value can change the query's meaning. PreparedStatement parameters are sent separately from the SQL text, so the input can never be interpreted as code. Always parameterise user input.
Transactions (brief)
By default each statement auto-commits. To group several changes so they all succeed or all fail, turn off auto-commit, then commit() or rollback().
conn.setAutoCommit(false);
try {
// ... several executeUpdate calls ...
conn.commit(); // make all changes permanent together
} catch (SQLException e) {
conn.rollback(); // undo everything on failure
}
Common mistakes
- Building SQL by string concatenation. This is the classic SQL-injection bug. Use
PreparedStatementplaceholders. - Not closing resources. Open connections and statements leak. Use
try-with-resources. - Forgetting the driver dependency. Without the database's JDBC driver on the classpath,
getConnectionfails with "No suitable driver". - Calling
getInt/getStringbeforers.next(). A freshResultSetpoints before the first row; you must callnext()first. - Hard-coding credentials. Load them from configuration or environment variables, not source code.
FAQ
Do I still need Class.forName(...) to load the driver? Modern JDBC (4.0+) auto-discovers drivers on the classpath, so the explicit Class.forName call is usually unnecessary.
Should I use JDBC directly in big apps? JDBC is the foundation; larger projects often layer a framework (such as an ORM) on top, but understanding raw JDBC makes those tools far clearer.
Keep going
Next, read and write files with File I/O in Java, or revisit Exception Handling in Java. All tutorials are on the Java hub; for guided practice in Jalgaon, see the Java course.
Build database-backed apps at Infoplanet, Jalgaon. Join the waitlist for the Java course.
Want to learn this properly?
Join the waitlist for our courses — beginner-friendly, project-first classes in Jalgaon.
Browse coursesFounder, Infoplanet
Atul Kabra founded Infoplanet in 2001 and has spent over two decades teaching programming — C, C++, Java, databases and more — to students across Maharashtra.
Related guides
Arrays in Java
Store many values of one type with Java arrays: declaring, initializing, indexing, iterating, multidimensional arrays, and the Arrays helper class.
Classes & Objects in Java
Define classes with fields and methods, create objects with new, use the this keyword, and understand instance vs static members in Java.
The Java Collections Framework
Use the Java Collections Framework — List, Set, and Map with ArrayList and HashMap — plus generics and iteration, to store flexible groups of objects.
