Java

Explain How to Connect Java Application to a Database Using JDBC with Example

By Utility Zone · 2025-11-06T11:17:13.615657

JDBC (Java Database Connectivity) is a Java-based API that enables Java applications to interact with databases. It provides a standardized interface for connecting to relational databases, executing SQL queries, and retrieving results, regardless of the underlying database system.1234

JDBC architecture layers and database connectivity workflow in Java applications

JDBC architecture layers and database connectivity workflow in Java applications


What is JDBC?

JDBC is a bridge between Java applications and databases. It allows you to write database-independent Java code that can work with different databases by simply changing the JDBC driver. JDBC follows a driver-based architecture where different database vendors provide their own JDBC drivers.134

Why Use JDBC?

  • Database Independence: Write code once, use with any JDBC-compliant database34
  • Standardized API: Consistent interface across different databases3
  • SQL Support: Execute any SQL query directly from Java3
  • Data Manipulation: Insert, update, delete, and retrieve data efficiently3
  • Exception Handling: Built-in SQLException for error handling5

JDBC Architecture

JDBC operates in layers, each with a specific responsibility:123

1. Java Application

  • Your Java code that uses JDBC to interact with databases3

2. JDBC API (java.sql package)

  • Provides interfaces and classes: Connection, Statement, PreparedStatement, ResultSet, SQLException3

3. JDBC Driver Manager

  • Manages JDBC drivers and creates database connections21
  • Routes requests to the appropriate driver

4. JDBC Drivers

  • Database-specific drivers (MySQL, PostgreSQL, Oracle, etc.)12
  • Translate JDBC calls into database-specific commands

5. Database

  • The actual relational database management system3

6-Step JDBC Process

All JDBC applications follow these standard steps:3

Step 1: Import JDBC Package

Import necessary JDBC classes for database operations:

import java.sql.*;  // Connection, Statement, ResultSet, etc.

Step 2: Load and Register the JDBC Driver

Load the JDBC driver class using Class.forName():63

try {
    Class.forName("com.mysql.cj.jdbc.Driver");  // MySQL
    // For other databases:
    // Class.forName("org.postgresql.Driver");  // PostgreSQL
    // Class.forName("oracle.jdbc.driver.OracleDriver");  // Oracle
} catch (ClassNotFoundException e) {
    System.out.println("Driver not found: " + e.getMessage());
}

Note: In newer JDBC versions (JDBC 4.0+), driver registration is automatic, but it's still good practice to register explicitly for compatibility.6

Step 3: Establish a Connection

Create a connection to the database using the JDBC URL, username, and password:16

String url = "jdbc:mysql://localhost:3306/mydatabase";
String user = "root";
String password = "your_password";

try {
    Connection connection = DriverManager.getConnection(url, user, password);
    System.out.println("Connected successfully!");
} catch (SQLException e) {
    System.out.println("Connection failed: " + e.getMessage());
}

JDBC Connection String Format:1

jdbc:<subprotocol>://<host>:<port>/<database>

Examples for Different Databases:61

  • MySQL: jdbc:mysql://localhost:3306/mydatabase
  • PostgreSQL: jdbc:postgresql://localhost:5432/mydatabase
  • Oracle: jdbc:oracle:thin:@localhost:1521:mydatabase
  • SQL Server: jdbc:sqlserver://localhost:1433;database=mydatabase

Step 4: Create a Statement

Create a Statement or PreparedStatement object to execute SQL queries:3

Using Statement (for simple queries):

Statement statement = connection.createStatement();

Using PreparedStatement (preferred for queries with parameters):7

String sql = "SELECT * FROM students WHERE id = ?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1, 101);  // Set parameter value

Step 5: Execute the Query

Execute SQL queries using appropriate methods:3

For SELECT queries (returns ResultSet):

ResultSet resultSet = preparedStatement.executeQuery();

For INSERT, UPDATE, DELETE (returns affected rows count):

int rowsAffected = preparedStatement.executeUpdate();

Step 6: Process Results and Close Resources

Retrieve data from ResultSet and close all resources:3

while (resultSet.next()) {
    int id = resultSet.getInt("id");
    String name = resultSet.getString("name");
    System.out.println("ID: " + id + ", Name: " + name);
}

// Close resources
resultSet.close();
preparedStatement.close();
connection.close();

Complete JDBC Example: Connecting to MySQL

Database Setup

First, create a MySQL database and table:3

CREATE DATABASE school;
USE school;

CREATE TABLE students (
    id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(50),
    age INT,
    gpa DOUBLE
);

INSERT INTO students VALUES (1, 'Amit', 20, 3.8), (2, 'Riya', 21, 3.9);

Java Code Example:3

import java.sql.*;

public class JDBCDemo {
    public static void main(String[] args) {
        // Connection details
        String url = "jdbc:mysql://localhost:3306/school";
        String user = "root";
        String password = "your_password";
        
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        
        try {
            // Step 1: Load Driver (optional in JDBC 4.0+)
            Class.forName("com.mysql.cj.jdbc.Driver");
            
            // Step 2: Create Connection
            connection = DriverManager.getConnection(url, user, password);
            System.out.println("✓ Connected to database");
            
            // Step 3: Create Statement
            statement = connection.createStatement();
            
            // Step 4: Execute Query
            String query = "SELECT * FROM students";
            resultSet = statement.executeQuery(query);
            
            // Step 5: Process Results
            System.out.println("\n--- Students List ---");
            while (resultSet.next()) {
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                int age = resultSet.getInt("age");
                double gpa = resultSet.getDouble("gpa");
                
                System.out.println("ID: " + id + ", Name: " + name + 
                                 ", Age: " + age + ", GPA: " + gpa);
            }
        } catch (ClassNotFoundException e) {
            System.out.println("Driver not found: " + e.getMessage());
        } catch (SQLException e) {
            System.out.println("SQL Error: " + e.getMessage());
            System.out.println("SQL State: " + e.getSQLState());
            System.out.println("Error Code: " + e.getErrorCode());
        } finally {
            // Step 6: Close Resources
            try {
                if (resultSet != null) resultSet.close();
                if (statement != null) statement.close();
                if (connection != null) connection.close();
                System.out.println("\n✓ Resources closed");
            } catch (SQLException e) {
                System.out.println("Error closing resources: " + e.getMessage());
            }
        }
    }
}

Output:

✓ Connected to database

--- Students List ---
ID: 1, Name: Amit, Age: 20, GPA: 3.8
ID: 2, Name: Riya, Age: 21, GPA: 3.9

✓ Resources closed

Using PreparedStatement (Recommended)

PreparedStatement is safer and more efficient than Statement, especially when using parameterized queries:7

import java.sql.*;

public class PreparedStatementExample {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/school";
        String user = "root";
        String password = "your_password";
        
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
            Connection connection = DriverManager.getConnection(url, user, password);
            
            // Using PreparedStatement
            String sql = "INSERT INTO students (name, age, gpa) VALUES (?, ?, ?)";
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            
            // Set parameter values
            preparedStatement.setString(1, "John");
            preparedStatement.setInt(2, 22);
            preparedStatement.setDouble(3, 3.7);
            
            // Execute update
            int rowsInserted = preparedStatement.executeUpdate();
            System.out.println(rowsInserted + " row(s) inserted");
            
            // SELECT example
            String selectSql = "SELECT * FROM students WHERE age > ?";
            PreparedStatement selectStmt = connection.prepareStatement(selectSql);
            selectStmt.setInt(1, 20);
            
            ResultSet rs = selectStmt.executeQuery();
            while (rs.next()) {
                System.out.println(rs.getString("name") + " - Age: " + rs.getInt("age"));
            }
            
            preparedStatement.close();
            selectStmt.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

Try-with-Resources (Best Practice for Resource Management)

Modern Java (Java 7+) uses try-with-resources for automatic resource management:489

import java.sql.*;

public class TryWithResourcesExample {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/school";
        String user = "root";
        String password = "your_password";
        
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        
        // Using try-with-resources - automatically closes resources
        try (Connection connection = DriverManager.getConnection(url, user, password);
             Statement statement = connection.createStatement();
             ResultSet resultSet = statement.executeQuery("SELECT * FROM students")) {
            
            while (resultSet.next()) {
                System.out.println(resultSet.getString("name") + 
                                 " - Age: " + resultSet.getInt("age"));
            }
        } catch (SQLException e) {
            System.out.println("Error: " + e.getMessage());
        }
        // Resources are automatically closed here
    }
}

Advantages:894

  • Automatic resource closure - no need for explicit close()
  • Cleaner, more readable code
  • Prevents resource leaks

Preventing SQL Injection

Use PreparedStatement with placeholders to prevent SQL injection attacks:101112

Vulnerable Code (DO NOT USE):

String name = userInput;  // Could contain malicious SQL
String query = "SELECT * FROM users WHERE name = '" + name + "'";

Secure Code (RECOMMENDED):

String query = "SELECT * FROM users WHERE name = ?";
PreparedStatement ps = connection.prepareStatement(query);
ps.setString(1, userInput);  // Safely escapes input
ResultSet rs = ps.executeQuery();

The ? placeholder and setString() method ensure that user input is properly escaped and treated as data, not SQL code.111210


Common PreparedStatement Methods7

MethodPurpose
setString(int index, String value)Set string value at parameter index
setInt(int index, int value)Set integer value at parameter index
setDouble(int index, double value)Set double value at parameter index
setFloat(int index, float value)Set float value at parameter index
setBoolean(int index, boolean value)Set boolean value at parameter index
setDate(int index, java.sql.Date value)Set date value at parameter index
executeQuery()Execute SELECT query, returns ResultSet
executeUpdate()Execute INSERT, UPDATE, DELETE, returns rows affected

Connection Pooling for Production Applications

For high-performance applications, use connection pooling instead of creating new connections each time:131415

// Using HikariCP (popular connection pool library)
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

public class DatabaseConnection {
    private static HikariDataSource dataSource;
    
    static {
        HikariConfig config = new HikariConfig();
        config.setJdbcUrl("jdbc:mysql://localhost:3306/school");
        config.setUsername("root");
        config.setPassword("password");
        config.setMaximumPoolSize(10);  // Maximum connections
        config.setMinimumIdle(5);       // Minimum connections
        dataSource = new HikariDataSource(config);
    }
    
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }
}

Benefits of Connection Pooling:1415

  • Reuses existing connections instead of creating new ones
  • Significantly improves performance
  • Reduces database overhead
  • Better resource management

Best Practices for JDBC

  1. Always Use PreparedStatement for parameterized queries710
  2. Use Try-with-Resources for automatic resource management489
  3. Implement Connection Pooling for production applications1415
  4. Handle Exceptions Properly with catch blocks and logging5
  5. Validate User Input before using it in queries12
  6. Store Credentials in configuration files or environment variables, never hardcode4
  7. Close Resources in finally block or use try-with-resources9
  8. Use Batch Operations for multiple inserts/updates for better performance
  9. Optimize Queries with proper indexes and fetch only needed data4

Common JDBC Exceptions

ExceptionCause
ClassNotFoundExceptionJDBC driver not found in classpath
SQLExceptionGeneric SQL error (most common)
SQLDataExceptionInvalid data type value
SQLIntegrityConstraintViolationExceptionPrimary key or unique constraint violation
SQLInvalidAuthorizationSpecExceptionInvalid username/password

Understanding JDBC is essential for building data-driven Java applications that interact reliably with databases. The combination of PreparedStatement, proper exception handling, and resource management creates robust, secure database connectivity in Java.134 <span style="display:none">1617181920</span>


<div align="center">⁂</div>

Footnotes

  1. https://dzone.com/articles/jdbc-tutorial-part-1-connecting-to-a-database ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9

  2. https://www.youtube.com/watch?v=03rDqI6lxdI ↩ ↩2 ↩3 ↩4

  3. https://www.geeksforgeeks.org/java/jdbc-tutorial/ ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9 ↩10 ↩11 ↩12 ↩13 ↩14 ↩15 ↩16 ↩17 ↩18

  4. https://dev.to/be11amer/a-comprehensive-guide-to-jdbc-in-java-how-it-works-and-best-practices-46eb ↩ ↩2 ↩3 ↩4 ↩5 ↩6 ↩7 ↩8 ↩9

  5. https://www.geeksforgeeks.org/java/how-to-handle-sqlexception-in-jdbc/ ↩ ↩2

  6. https://www.cogentuniversity.com/post/5-steps-for-database-connectivity-with-jdbc ↩ ↩2 ↩3 ↩4

  7. https://www.geeksforgeeks.org/java/how-to-use-preparedstatement-in-java/ ↩ ↩2 ↩3 ↩4

  8. https://www.tutorialspoint.com/how-do-we-close-resources-automatically-in-java ↩ ↩2 ↩3

  9. https://www.tutorialspoint.com/how-to-use-try-with-resources-with-jdbc ↩ ↩2 ↩3 ↩4

  10. https://www.geeksforgeeks.org/java/how-to-handle-sql-injection-in-jdbc-using-preparedstatement/ ↩ ↩2 ↩3

  11. https://stackoverflow.com/questions/9516625/prevent-sql-injection-attacks-in-a-java-program ↩ ↩2

  12. https://www.acunetix.com/how-to-prevent-sql-injections-java/ ↩ ↩2 ↩3

  13. https://www.postgresql.org/docs/7.4/jdbc-datasource.html ↩

  14. https://www.progress.com/tutorials/jdbc/jdbc-jdbc-connection-pooling ↩ ↩2 ↩3

  15. https://javaranch.com/journal/200601/JDBCConnectionPooling.html ↩ ↩2 ↩3

  16. https://stackoverflow.com/questions/14898672/how-do-i-troubleshoot-why-drivermanager-getconnection-is-returning-null ↩

  17. https://www.ibm.com/docs/en/i/7.4.0?topic=preparedstatements-example-using-preparedstatement-obtain-resultset ↩

  18. https://www.ibm.com/docs/en/i/7.3?topic=preparedstatements-example-using-preparedstatement-obtain-resultset ↩

  19. https://dev.mysql.com/doc/connector-j/en/connector-j-usagenotes-connect-drivermanager.html ↩

  20. https://stackoverflow.com/questions/5117191/spring-jdbc-connection-pool-best-practices ↩