[!NOTE] Until now, variables disappeared when the program closed. To build real applications, you need persistent state. Java Database Connectivity (JDBC) is the official API used to connect Java directly to relational databases.
The JDBC Architecture Pipeline
Whether you are connecting to Oracle, PostgreSQL, or MySQL, JDBC uses the exact same interface code. You just drop in the correct "Driver" binary file provided by your specific database company.
The Pipeline:
- Securely Connect to the Database.
- Create a SQL Statement.
- Execute the Statement.
- Process the returned ResultSet.
- Close the connection to prevent memory leaks!
Example: Selecting Data
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class DatabaseExample {
public static void main(String[] args) {
String url = "jdbc:postgresql://localhost:5432/my_company";
String user = "admin";
String pwd = "super_secret_password";
// We wrap database connections in Try-Catch because networking can fail!
try (Connection conn = DriverManager.getConnection(url, user, pwd)) {
System.out.println("Connection physically established to PostgreSQL!");
// Create the Query Object
Statement stmt = conn.createStatement();
// Execute the raw query safely!
String sql = "SELECT id, username, permission_level FROM users";
ResultSet rs = stmt.executeQuery(sql);
// Iterate through the results vertically!
while (rs.next()) {
// Extract column data from the current row
int id = rs.getInt("id");
String name = rs.getString("username");
System.out.println("Row Scanned! ID: " + id + ", Name: " + name);
}
} catch (Exception e) {
System.err.println("Fatal Database Connection Error!");
e.printStackTrace();
}
}
}
The Terror of SQL Injection
If your application asks the user to type in their "Username" into an HTML form to trigger a SELECT check, a malicious hacker can type in exactly this string:
'; DROP TABLE users; --
If you blindly concatenate their string directly into your raw SQL format:
"SELECT * FROM users WHERE name = '" + userInput + "';"
You will physically transmit the command to drop the entire table, instantly wiping production data.
The Fix: PreparedStatement
Never, ever use string concatenation for SQL queries. Always use PreparedStatement. It mathematically escapes hacker strings safely as raw text.
// 1. The '?' acts as an armored parameter slot
String safeSql = "SELECT * FROM users WHERE username = ?";
// 2. PreparedStatement pre-compiles the query defensively
PreparedStatement pstmt = conn.prepareStatement(safeSql);
// 3. You inject the user's string. If they typed '; DROP TABLE', it is safely escaped!
pstmt.setString(1, userInput);
ResultSet rs = pstmt.executeQuery();
JDBC in Real Applications
JDBC is the low-level bridge between Java and relational databases. Even if you later use Spring Data JPA or Hibernate, understanding JDBC helps you understand connections, statements, result sets, and transactions.
Use try-with-resources
String sql = "SELECT id, username FROM users WHERE username = ?";
try (
Connection connection = dataSource.getConnection();
PreparedStatement statement = connection.prepareStatement(sql)
) {
statement.setString(1, username);
try (ResultSet rs = statement.executeQuery()) {
while (rs.next()) {
System.out.println(rs.getString("username"));
}
}
}
This pattern closes the connection, statement, and result set automatically.
Transaction Shape
connection.setAutoCommit(false);
try {
// execute multiple related updates
connection.commit();
} catch (SQLException e) {
connection.rollback();
throw e;
}
Common Mistakes
- Building SQL by concatenating user input.
- Forgetting to close database resources.
- Not using transactions for multi-step updates.
- Fetching too many rows when pagination is needed.
Mini Practice
Write a prepared statement for finding a user by email. Then write a second example that updates marks and commits only when both related updates succeed.
Practice Lab: Prepared Statement Design
Write JDBC code shape that avoids SQL injection and resource leaks.
- Write SQL with a parameter placeholder:
SELECT * FROM users WHERE email = ?. - Create a
PreparedStatement. - Set the email parameter using
setString. - Read rows with
ResultSetandrs.next(). - Wrap resources in try-with-resources.
Goal: Practice the safe JDBC query shape before connecting to a real database.
Revision Checkpoint
- JDBC: Java API for relational database access.
Connection: Link to database.PreparedStatement: Parameterized SQL; helps prevent injection.ResultSet: Cursor over returned rows.- Transaction: Commit all related changes or roll back together.
Before the quiz: Explain why user input should never be concatenated into SQL.