Programming in Java

Unit 14: JDBC Database Programming

From raw SQL to enterprise CRUD apps โ€” master JDBC architecture, driver types, PreparedStatement, transactions, and build real database applications in Java.

โฑ๏ธ Time to Complete: 7 hrs theory + 6 hrs lab  |  ๐Ÿ’ฐ Earning Potential: โ‚น10Kโ€“โ‚น40K/month  |  ๐Ÿ“ 30 MCQs (Bloom's Mapped)

๐Ÿ’ผ Jobs this unlocks: Java Backend Developer (โ‚น5โ€“10 LPA)  |  Full-Stack Developer (โ‚น6โ€“14 LPA)  |  Database Application Developer (โ‚น4โ€“8 LPA)

Section A

Opening Hook โ€” The Database Behind Every Ticket

๐Ÿš‚ How IRCTC Handles 12 Lakh Simultaneous Database Queries During Tatkal

Every morning at 10:00 AM, millions of Indians slam the IRCTC booking page. In a 60-second Tatkal window, the system handles 12 lakh (1.2 million) simultaneous database queries. Each search, each seat check, each booking confirmation is a JDBC PreparedStatement flying through a managed connection pool to an Oracle/PostgreSQL database backend.

Behind the scenes, IRCTC's Java application servers maintain pools of pre-opened database connections (using HikariCP/C3P0). When you click "Book Now," your request grabs a connection from the pool, executes a parameterised SQL query (SELECT available_seats FROM trains WHERE train_no=? AND date=?), reads the ResultSet, and if seats exist, fires an INSERT INTO bookings โ€” all within 200 milliseconds.

Every ticket you book = one JDBC call. Every "Seat not available" pop-up = another JDBC call. Every payment confirmation = yet another JDBC call. Without JDBC, there is no IRCTC, no online banking, no e-commerce checkout, no digital India.

๐Ÿ‡ฎ๐Ÿ‡ณ IRCTC๐Ÿ‡ฎ๐Ÿ‡ณ SBI YONO๐Ÿ‡ฎ๐Ÿ‡ณ Paytm๐Ÿ‡ฎ๐Ÿ‡ณ Infosys๐Ÿ‡ฎ๐Ÿ‡ณ TCS๐Ÿ‡ฎ๐Ÿ‡ณ Flipkart
India processes over 10 billion UPI transactions per month. Every single one of those transactions involves multiple JDBC calls โ€” checking balance, debiting sender, crediting receiver, logging audit trail. That's 40+ billion JDBC operations per month just for UPI alone. The java.sql package is literally the backbone of India's digital payments infrastructure.
Section B

Learning Outcomes โ€” Bloom's Taxonomy Mapped

Bloom's LevelLearning Outcome
๐Ÿ”ต RememberList the four components of JDBC API (Driver, Connection, Statement, ResultSet) and name the four JDBC driver types
๐Ÿ”ต RememberRecall the syntax for DriverManager.getConnection() and the steps to execute a SQL query in Java
๐ŸŸข UnderstandExplain the difference between Statement, PreparedStatement, and CallableStatement with real-world examples
๐ŸŸข UnderstandDescribe how SQL injection attacks work and why PreparedStatement prevents them
๐ŸŸก ApplyWrite complete Java CRUD programs (INSERT, SELECT, UPDATE, DELETE) using PreparedStatement with MySQL
๐ŸŸก ApplyImplement transaction management using setAutoCommit(false), commit(), and rollback()
๐ŸŸ  AnalyzeCompare the four JDBC driver types and determine which is suitable for different deployment scenarios
๐ŸŸ  AnalyzeAnalyze connection pooling benefits and diagnose connection leak problems in a Java application
๐Ÿ”ด EvaluateEvaluate whether a given code snippet is vulnerable to SQL injection and propose fixes
๐Ÿ”ด EvaluateAssess the trade-offs between batch processing vs individual inserts for bulk data operations
๐ŸŸฃ CreateDesign and build a complete College Library CRUD application with MySQL backend
๐ŸŸฃ CreateArchitect a Student Marks Entry System with transaction-safe multi-table updates
Section C

Concept Explanation โ€” JDBC from Scratch

1. JDBC Architecture โ€” The 4-Tier Bridge

Think of JDBC as a universal translator between your Java program and any database. Just like a NEFT wire transfer โ€” your Java app (your bank) sends SQL (payment instruction) through JDBC (banking network) to the Database (recipient bank). You don't need to know the internal workings of the recipient bank; JDBC handles the protocol.

๐Ÿ—๏ธ JDBC 4-Tier Architecture

Tier 1 โ€” Java Application: Your Java code that creates SQL queries, processes results, and handles business logic. This is what YOU write.

Tier 2 โ€” JDBC API: The java.sql and javax.sql packages. Provides interfaces like Connection, Statement, ResultSet, PreparedStatement. This is the "contract" โ€” it defines WHAT can be done.

Tier 3 โ€” JDBC Driver Manager & Driver: The DriverManager class loads the appropriate driver. The driver itself (e.g., MySQL Connector/J, Oracle JDBC) implements the JDBC interfaces. This is the "translator" โ€” it knows HOW to talk to a specific database.

Tier 4 โ€” Database: The actual database server (MySQL, PostgreSQL, Oracle, SQL Server). Stores data, executes SQL, returns results.

Architecture Diagram
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   JAVA APPLICATION   โ”‚  โ† Your code (main(), servlets, Spring)
โ”‚   (Tier 1)           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚  calls java.sql API
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚      JDBC API        โ”‚  โ† Interfaces: Connection, Statement,
โ”‚   (Tier 2)           โ”‚     ResultSet, PreparedStatement
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚  delegates to driver
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚   JDBC DRIVER        โ”‚  โ† mysql-connector-j.jar / ojdbc.jar
โ”‚   (Tier 3)           โ”‚     Translates JDBC calls โ†’ DB protocol
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚  network (TCP/IP)
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚     DATABASE         โ”‚  โ† MySQL, PostgreSQL, Oracle, SQL Server
โ”‚   (Tier 4)           โ”‚     Executes SQL, returns rows
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
SBI's YONO app uses this exact 4-tier architecture. The mobile app (Tier 1) calls Java backend services that use JDBC API (Tier 2) with Oracle JDBC driver (Tier 3) to connect to Oracle Database (Tier 4). When you check your balance on YONO, a JDBC SELECT query runs against the Oracle DB โ€” and the result appears on your screen in under 500ms.

2. JDBC API Overview โ€” The Core Interfaces

The JDBC API lives in two packages: java.sql (core) and javax.sql (extensions like connection pooling, RowSets). Here are the key players:

Interface / ClassWhat It DoesAnalogy
DriverManagerFactory that creates Connection objects. Loads the right driver for your DB URL.Like a telephone exchange โ€” you dial a number (URL), it connects you to the right person (database)
ConnectionRepresents an active session with the database. Used to create statements and manage transactions.Like an open phone line โ€” you can talk (send SQL) as long as the connection is alive
StatementSends static SQL strings to the database. Simple but vulnerable to SQL injection.Like a postcard โ€” anyone can read and modify the message
PreparedStatementPre-compiled SQL with ? placeholders. Faster, safer, reusable.Like a sealed registered letter โ€” the message template is fixed, only the data changes
CallableStatementCalls stored procedures in the database.Like calling a specialist โ€” you don't tell them how to operate, just what you need done
ResultSetHolds rows returned by a SELECT query. Navigate with next(), read with getInt(), getString().Like a stack of answer sheets โ€” you flip through one by one, reading each student's marks

The 5-Step JDBC Workflow

Java
// Step 1: Load the driver (auto-loaded in JDBC 4.0+)
// Class.forName("com.mysql.cj.jdbc.Driver");  // Only needed for older JDBC

// Step 2: Establish connection
Connection conn = DriverManager.getConnection(
    "jdbc:mysql://localhost:3306/college_db",
    "root", "password");

// Step 3: Create statement
PreparedStatement pstmt = conn.prepareStatement(
    "SELECT * FROM students WHERE roll_no = ?");
pstmt.setInt(1, 101);

// Step 4: Execute query & process ResultSet
ResultSet rs = pstmt.executeQuery();
while (rs.next()) {
    System.out.println(rs.getString("name") + " โ€” " + rs.getInt("marks"));
}

// Step 5: Close resources (reverse order)
rs.close();
pstmt.close();
conn.close();
Never hardcode credentials in production code! The URL, username, and password shown above are for learning only. In real projects (TCS, Infosys), credentials come from environment variables, properties files, or secret managers. Hardcoded passwords in source code = instant security audit failure.

3. JDBC Driver Types โ€” Type 1 to Type 4

A JDBC driver is the "translator" that converts JDBC calls into the specific protocol your database understands. There are four types, each with different trade-offs:

TypeNameHow It WorksProsConsUsed Today?
Type 1JDBC-ODBC BridgeJDBC โ†’ ODBC โ†’ Database. Uses Windows ODBC drivers as middleware.Easy setup for MS AccessSlow, platform-dependent, removed in Java 8+โŒ Obsolete
Type 2Native-API DriverJDBC โ†’ Native C/C++ library โ†’ Database. Requires DB vendor's native client installed.Faster than Type 1Platform-dependent, requires native installationโš ๏ธ Rare (Oracle OCI)
Type 3Network Protocol DriverJDBC โ†’ Middleware server โ†’ Database. 3-tier architecture via a middleware application server.No client-side DB library neededRequires middleware server, extra network hopโš ๏ธ Niche (app servers)
Type 4Thin Driver (Pure Java)JDBC โ†’ Database directly via TCP/IP. 100% Java, no native code.Fastest, platform-independent, no extra installationDB-specific (one driver per DB)โœ… Industry standard
In 2024, always use Type 4 drivers. MySQL Connector/J, PostgreSQL JDBC Driver, Oracle Thin Driver โ€” all are Type 4. If an interviewer asks "which JDBC driver type do you use?", the answer is Type 4 (Thin/Pure Java). Type 1 is removed since Java 8. Types 2 & 3 are legacy.

4. Statement vs PreparedStatement vs CallableStatement

FeatureStatementPreparedStatementCallableStatement
SQL TypeStatic SQL stringsParameterised SQL with ?Stored procedure calls
CompilationCompiled every executionPre-compiled once, executed many timesPre-compiled stored procedure
PerformanceSlowest (re-parsed each time)Fast (cached execution plan)Fastest (DB-side optimised)
SQL InjectionโŒ Vulnerableโœ… Safe (parameterised)โœ… Safe
Use CaseQuick testing, DDL (CREATE TABLE)All CRUD operationsComplex business logic in DB
Examplestmt.execute("DROP TABLE...")pstmt.setString(1, name)cstmt.registerOutParameter(...)

โš ๏ธ SQL Injection โ€” Why Statement is Dangerous

Java โ€” VULNERABLE CODE
// โŒ DANGEROUS: String concatenation with user input
String userInput = "'; DROP TABLE students; --";
String sql = "SELECT * FROM students WHERE name = '" + userInput + "'";
stmt.execute(sql);
// Executed SQL: SELECT * FROM students WHERE name = ''; DROP TABLE students; --'
// ๐Ÿ’€ YOUR ENTIRE STUDENTS TABLE IS DELETED!
Java โ€” SAFE CODE
// โœ… SAFE: PreparedStatement treats input as DATA, not SQL code
String userInput = "'; DROP TABLE students; --";
PreparedStatement pstmt = conn.prepareStatement(
    "SELECT * FROM students WHERE name = ?");
pstmt.setString(1, userInput);
ResultSet rs = pstmt.executeQuery();
// The input is treated as a literal string โ€” no SQL execution.
// โœ… Table is SAFE. Query returns 0 rows (no student with that silly name).
In 2023, an Indian fintech startup lost โ‚น2.3 crore to a SQL injection attack because a junior developer used Statement with string concatenation instead of PreparedStatement. The attacker extracted 50,000 customer records including PAN numbers. CERT-In now mandates parameterised queries for all government and BFSI applications.

5. ResultSet Navigation

A ResultSet is like a cursor pointing to rows returned by a SELECT query. You start before the first row and call next() to advance:

MethodWhat It DoesReturn Type
next()Moves cursor to next row. Returns false when no more rows.boolean
getInt("column")Gets integer value from named columnint
getString("column")Gets string value from named columnString
getDouble("column")Gets double value from named columndouble
getDate("column")Gets date value from named columnjava.sql.Date
getInt(1)Gets value by column index (1-based)int
wasNull()Checks if the last value read was SQL NULLboolean
Java
ResultSet rs = pstmt.executeQuery();

// Pattern: while loop with next()
while (rs.next()) {
    int rollNo     = rs.getInt("roll_no");
    String name    = rs.getString("name");
    double marks   = rs.getDouble("marks");
    Date dob       = rs.getDate("dob");

    System.out.printf("%-5d %-20s %.1f  %s%n", rollNo, name, marks, dob);
}
rs.close();
Column indices in ResultSet are 1-based, NOT 0-based! rs.getInt(1) returns the FIRST column. rs.getInt(0) throws SQLException. This trips up every Java student who is used to 0-based arrays.

6. CRUD Operations โ€” Full Code for Each

Setup: Create the Database & Table

SQL โ€” Run in MySQL
CREATE DATABASE college_db;
USE college_db;

CREATE TABLE books (
    book_id    INT PRIMARY KEY AUTO_INCREMENT,
    title      VARCHAR(100) NOT NULL,
    author     VARCHAR(80),
    isbn       VARCHAR(20) UNIQUE,
    price      DECIMAL(8,2),
    copies     INT DEFAULT 1,
    added_date DATE DEFAULT (CURRENT_DATE)
);

CREATE โ€” INSERT a new book

Java
import java.sql.*;

public class InsertBook {
    public static void main(String[] args) {
        String url  = "jdbc:mysql://localhost:3306/college_db";
        String user = "root";
        String pass = "password";

        String sql = "INSERT INTO books (title, author, isbn, price, copies) VALUES (?, ?, ?, ?, ?)";

        try (Connection conn = DriverManager.getConnection(url, user, pass);
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setString(1, "Data Structures Using Java");
            pstmt.setString(2, "R. Lafore");
            pstmt.setString(3, "978-0-13-257627-7");
            pstmt.setDouble(4, 599.00);
            pstmt.setInt(5, 5);

            int rows = pstmt.executeUpdate();
            System.out.println(rows + " book(s) inserted successfully!");

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
1 book(s) inserted successfully!

READ โ€” SELECT all books

Java
public class SelectBooks {
    public static void main(String[] args) {
        String url  = "jdbc:mysql://localhost:3306/college_db";
        String sql  = "SELECT * FROM books ORDER BY title";

        try (Connection conn = DriverManager.getConnection(url, "root", "password");
             PreparedStatement pstmt = conn.prepareStatement(sql);
             ResultSet rs = pstmt.executeQuery()) {

            System.out.printf("%-5s %-30s %-20s %-10s %-6s%n",
                "ID", "Title", "Author", "Price(โ‚น)", "Copies");
            System.out.println("โ€”".repeat(75));

            while (rs.next()) {
                System.out.printf("%-5d %-30s %-20s โ‚น%-9.2f %-6d%n",
                    rs.getInt("book_id"),
                    rs.getString("title"),
                    rs.getString("author"),
                    rs.getDouble("price"),
                    rs.getInt("copies"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
ID Title Author Price(โ‚น) Copies โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€”โ€” 1 Data Structures Using Java R. Lafore โ‚น599.00 5

UPDATE โ€” Modify book price

Java
public class UpdateBook {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/college_db";
        String sql = "UPDATE books SET price = ?, copies = ? WHERE book_id = ?";

        try (Connection conn = DriverManager.getConnection(url, "root", "password");
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setDouble(1, 649.00);   // new price
            pstmt.setInt(2, 10);         // new copies
            pstmt.setInt(3, 1);          // book_id

            int rows = pstmt.executeUpdate();
            System.out.println(rows + " book(s) updated.");

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
1 book(s) updated.

DELETE โ€” Remove a book

Java
public class DeleteBook {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/college_db";
        String sql = "DELETE FROM books WHERE book_id = ?";

        try (Connection conn = DriverManager.getConnection(url, "root", "password");
             PreparedStatement pstmt = conn.prepareStatement(sql)) {

            pstmt.setInt(1, 1);  // book_id to delete

            int rows = pstmt.executeUpdate();
            if (rows > 0)
                System.out.println("Book deleted successfully.");
            else
                System.out.println("No book found with that ID.");

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
Book deleted successfully.

7. Transaction Management

A transaction is a group of SQL operations that must ALL succeed or ALL fail. Think of it like a bank transfer: debit from Account A AND credit to Account B must both happen โ€” or neither should.

๐Ÿ”„ ACID Properties

A โ€” Atomicity: All operations succeed or all are rolled back. No partial execution.

C โ€” Consistency: Database moves from one valid state to another. No rule violations.

I โ€” Isolation: Concurrent transactions don't interfere with each other.

D โ€” Durability: Once committed, data survives crashes.

Java โ€” Transaction Example: Library Book Issue
public class IssueBookTransaction {
    public static void main(String[] args) {
        String url = "jdbc:mysql://localhost:3306/college_db";
        Connection conn = null;

        try {
            conn = DriverManager.getConnection(url, "root", "password");

            // โ‘  Disable auto-commit โ€” start transaction
            conn.setAutoCommit(false);

            // โ‘ก Decrease copies in books table
            PreparedStatement ps1 = conn.prepareStatement(
                "UPDATE books SET copies = copies - 1 WHERE book_id = ? AND copies > 0");
            ps1.setInt(1, 101);
            int updated = ps1.executeUpdate();

            if (updated == 0) {
                throw new SQLException("No copies available!");
            }

            // โ‘ข Insert issue record
            PreparedStatement ps2 = conn.prepareStatement(
                "INSERT INTO book_issues (book_id, student_id, issue_date) VALUES (?, ?, CURDATE())");
            ps2.setInt(1, 101);
            ps2.setInt(2, 2023001);
            ps2.executeUpdate();

            // โ‘ฃ COMMIT โ€” both operations succeed
            conn.commit();
            System.out.println("โœ… Book issued successfully!");

        } catch (SQLException e) {
            try {
                if (conn != null) {
                    // โ‘ค ROLLBACK โ€” undo everything if any step fails
                    conn.rollback();
                    System.out.println("โŒ Transaction rolled back: " + e.getMessage());
                }
            } catch (SQLException ex) { ex.printStackTrace(); }
        } finally {
            try {
                if (conn != null) {
                    conn.setAutoCommit(true);
                    conn.close();
                }
            } catch (SQLException e) { e.printStackTrace(); }
        }
    }
}

8. Batch Processing

When you need to insert 1,000 records, executing 1,000 individual queries is painfully slow (1,000 network round trips). Batch processing bundles them into a single trip:

Java โ€” Batch INSERT
String sql = "INSERT INTO students (name, roll_no, branch) VALUES (?, ?, ?)";
PreparedStatement pstmt = conn.prepareStatement(sql);

String[][] data = {
    {"Amit Sharma",  "101", "CSE"},
    {"Priya Verma",  "102", "IT"},
    {"Rahul Singh",  "103", "ECE"},
    {"Sneha Patel",  "104", "CSE"},
    {"Vikram Reddy", "105", "ME"}
};

for (String[] row : data) {
    pstmt.setString(1, row[0]);
    pstmt.setInt(2, Integer.parseInt(row[1]));
    pstmt.setString(3, row[2]);
    pstmt.addBatch();  // add to batch, don't execute yet
}

int[] results = pstmt.executeBatch();  // execute ALL at once!
System.out.println("Inserted " + results.length + " records in one batch.");
Inserted 5 records in one batch.

9. Connection Pooling

Problem: Creating a new database connection takes 200โ€“500ms (TCP handshake + authentication). If your app gets 100 requests/second, creating 100 new connections per second is a disaster.

Solution: Connection Pooling. Keep a "pool" of pre-created connections. When a request needs a connection, borrow one from the pool. When done, return it (don't close it). Think of it like an auto-rickshaw stand โ€” rickshaws wait in a line, passengers take the next available one, and the rickshaw returns to the stand after the trip.

FeatureWithout PoolWith Pool (HikariCP)
Connection time per request200โ€“500ms~1ms (pre-created)
Max concurrent connectionsUnlimited (DB crashes)Configurable (e.g., 10โ€“50)
Resource managementManual close (leak risk)Auto-reclaim idle connections
Production readinessโŒโœ…
Java โ€” HikariCP Connection Pool (Conceptual)
// In pom.xml: add com.zaxxer:HikariCP:5.1.0 dependency

HikariConfig config = new HikariConfig();
config.setJdbcUrl("jdbc:mysql://localhost:3306/college_db");
config.setUsername("root");
config.setPassword("password");
config.setMaximumPoolSize(10);  // max 10 connections in pool

HikariDataSource ds = new HikariDataSource(config);

// Get connection from pool (near-instant!)
try (Connection conn = ds.getConnection()) {
    // use connection...
}  // auto-returned to pool on close
IRCTC uses connection pooling to survive Tatkal rush. Without pooling, 12 lakh simultaneous users would mean 12 lakh new TCP connections to Oracle DB โ€” instant crash. With a pool of ~500 connections, requests queue up and reuse connections efficiently. HikariCP is the default pool in Spring Boot โ€” used by Paytm, PhonePe, and most Indian Java shops.

10. RowSet โ€” Disconnected Data Access

A RowSet is a wrapper around ResultSet that can work in disconnected mode. It fetches data, closes the connection, and lets you work with the data offline. Think of it like downloading a PDF vs reading online โ€” you can read the PDF even without internet.

TypeConnected?Use Case
JdbcRowSetโœ… ConnectedEnhanced ResultSet wrapper
CachedRowSetโŒ DisconnectedWork with data offline, sync later
WebRowSetโŒ DisconnectedXML-based data transfer
FilteredRowSetโŒ DisconnectedClient-side filtering
JoinRowSetโŒ DisconnectedJoin data from multiple RowSets

11. Database Metadata

DatabaseMetaData lets your Java program discover information about the database โ€” name, version, tables, columns โ€” programmatically:

Java
DatabaseMetaData meta = conn.getMetaData();
System.out.println("Database: " + meta.getDatabaseProductName());
System.out.println("Version:  " + meta.getDatabaseProductVersion());
System.out.println("Driver:   " + meta.getDriverName());
System.out.println("URL:      " + meta.getURL());

// List all tables
ResultSet tables = meta.getTables(null, null, "%", new String[]{"TABLE"});
while (tables.next()) {
    System.out.println("Table: " + tables.getString("TABLE_NAME"));
}
Database: MySQL Version: 8.0.35 Driver: MySQL Connector/J URL: jdbc:mysql://localhost:3306/college_db Table: books Table: book_issues Table: students

12. Full Application โ€” College Library CRUD App

Java โ€” LibraryCRUD.java
import java.sql.*;
import java.util.Scanner;

public class LibraryCRUD {
    private static final String URL  = "jdbc:mysql://localhost:3306/college_db";
    private static final String USER = "root";
    private static final String PASS = "password";

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("\n๐Ÿ“š COLLEGE LIBRARY SYSTEM");
            System.out.println("1. Add Book");
            System.out.println("2. Search Books");
            System.out.println("3. Update Book");
            System.out.println("4. Delete Book");
            System.out.println("5. View All Books");
            System.out.println("0. Exit");
            System.out.print("Choose: ");
            int choice = sc.nextInt(); sc.nextLine();

            switch (choice) {
                case 1: addBook(sc);      break;
                case 2: searchBooks(sc);  break;
                case 3: updateBook(sc);   break;
                case 4: deleteBook(sc);   break;
                case 5: viewAllBooks();   break;
                case 0: System.out.println("Goodbye!"); return;
                default: System.out.println("Invalid choice.");
            }
        }
    }

    static void addBook(Scanner sc) {
        System.out.print("Title: ");   String title  = sc.nextLine();
        System.out.print("Author: ");  String author = sc.nextLine();
        System.out.print("ISBN: ");    String isbn   = sc.nextLine();
        System.out.print("Price: ");   double price  = sc.nextDouble();
        System.out.print("Copies: ");  int copies    = sc.nextInt();

        String sql = "INSERT INTO books (title, author, isbn, price, copies) VALUES (?,?,?,?,?)";
        try (Connection c = DriverManager.getConnection(URL,USER,PASS);
             PreparedStatement p = c.prepareStatement(sql)) {
            p.setString(1,title); p.setString(2,author);
            p.setString(3,isbn);  p.setDouble(4,price);
            p.setInt(5,copies);
            System.out.println("โœ… " + p.executeUpdate() + " book added.");
        } catch (SQLException e) { System.out.println("Error: "+e.getMessage()); }
    }

    static void searchBooks(Scanner sc) {
        System.out.print("Search keyword: ");
        String kw = "%" + sc.nextLine() + "%";
        String sql = "SELECT * FROM books WHERE title LIKE ? OR author LIKE ?";
        try (Connection c = DriverManager.getConnection(URL,USER,PASS);
             PreparedStatement p = c.prepareStatement(sql)) {
            p.setString(1,kw); p.setString(2,kw);
            ResultSet rs = p.executeQuery();
            while (rs.next()) {
                System.out.printf("[%d] %s by %s โ€” โ‚น%.2f (%d copies)%n",
                    rs.getInt("book_id"), rs.getString("title"),
                    rs.getString("author"), rs.getDouble("price"),
                    rs.getInt("copies"));
            }
        } catch (SQLException e) { e.printStackTrace(); }
    }

    static void updateBook(Scanner sc) {
        System.out.print("Book ID to update: "); int id = sc.nextInt(); sc.nextLine();
        System.out.print("New price: ");         double price = sc.nextDouble();
        System.out.print("New copies: ");        int copies = sc.nextInt();
        String sql = "UPDATE books SET price=?, copies=? WHERE book_id=?";
        try (Connection c = DriverManager.getConnection(URL,USER,PASS);
             PreparedStatement p = c.prepareStatement(sql)) {
            p.setDouble(1,price); p.setInt(2,copies); p.setInt(3,id);
            System.out.println("โœ… " + p.executeUpdate() + " book updated.");
        } catch (SQLException e) { e.printStackTrace(); }
    }

    static void deleteBook(Scanner sc) {
        System.out.print("Book ID to delete: "); int id = sc.nextInt();
        String sql = "DELETE FROM books WHERE book_id=?";
        try (Connection c = DriverManager.getConnection(URL,USER,PASS);
             PreparedStatement p = c.prepareStatement(sql)) {
            p.setInt(1,id);
            System.out.println("๐Ÿ—‘๏ธ " + p.executeUpdate() + " book deleted.");
        } catch (SQLException e) { e.printStackTrace(); }
    }

    static void viewAllBooks() {
        String sql = "SELECT * FROM books ORDER BY title";
        try (Connection c = DriverManager.getConnection(URL,USER,PASS);
             PreparedStatement p = c.prepareStatement(sql);
             ResultSet rs = p.executeQuery()) {
            System.out.printf("%-5s %-30s %-20s %-10s %-6s%n",
                "ID","Title","Author","Price","Copies");
            while (rs.next()) {
                System.out.printf("%-5d %-30s %-20s โ‚น%-9.2f %-6d%n",
                    rs.getInt(1),rs.getString(2),rs.getString(3),
                    rs.getDouble(5),rs.getInt(6));
            }
        } catch (SQLException e) { e.printStackTrace(); }
    }
}

13. Full Application โ€” Student Marks Entry System

SQL โ€” Setup
CREATE TABLE students (
    student_id  INT PRIMARY KEY,
    name        VARCHAR(60) NOT NULL,
    branch      VARCHAR(10),
    semester    INT
);

CREATE TABLE marks (
    mark_id     INT PRIMARY KEY AUTO_INCREMENT,
    student_id  INT,
    subject     VARCHAR(40),
    marks_obt   INT,
    max_marks   INT DEFAULT 100,
    FOREIGN KEY (student_id) REFERENCES students(student_id)
);
Java โ€” StudentMarksSystem.java
import java.sql.*;
import java.util.Scanner;

public class StudentMarksSystem {
    static final String URL = "jdbc:mysql://localhost:3306/college_db";

    public static void main(String[] args) throws SQLException {
        Scanner sc = new Scanner(System.in);
        System.out.print("Enter Student ID: ");
        int sid = sc.nextInt(); sc.nextLine();
        System.out.print("Enter Name: ");
        String name = sc.nextLine();
        System.out.print("Branch: ");
        String branch = sc.nextLine();
        System.out.print("Semester: ");
        int sem = sc.nextInt(); sc.nextLine();

        Connection conn = DriverManager.getConnection(URL, "root", "password");
        conn.setAutoCommit(false);  // transaction start

        try {
            // Insert student
            PreparedStatement ps1 = conn.prepareStatement(
                "INSERT INTO students (student_id, name, branch, semester) VALUES (?,?,?,?)");
            ps1.setInt(1,sid); ps1.setString(2,name);
            ps1.setString(3,branch); ps1.setInt(4,sem);
            ps1.executeUpdate();

            // Insert marks for 5 subjects
            String[] subjects = {"Java", "DBMS", "OS", "Maths", "English"};
            PreparedStatement ps2 = conn.prepareStatement(
                "INSERT INTO marks (student_id, subject, marks_obt) VALUES (?,?,?)");

            for (String sub : subjects) {
                System.out.print("Marks in " + sub + ": ");
                int m = sc.nextInt();
                ps2.setInt(1, sid);
                ps2.setString(2, sub);
                ps2.setInt(3, m);
                ps2.addBatch();
            }
            ps2.executeBatch();

            conn.commit();  // all or nothing
            System.out.println("โœ… Student & marks saved successfully!");

        } catch (SQLException e) {
            conn.rollback();
            System.out.println("โŒ Rolled back: " + e.getMessage());
        } finally {
            conn.setAutoCommit(true);
            conn.close();
        }
    }
}
Section D

Learn by Doing โ€” 3-Tier Lab: College Library CRUD with MySQL

๐ŸŸข Tier 1 โ€” GUIDED: Setup MySQL + First JDBC Connection

โฑ๏ธ 60โ€“90 minutesBeginnerZero JDBC experience assumed

Step 1: Install MySQL Server

Download MySQL Community Server from dev.mysql.com/downloads. During setup, set root password to password (for learning only). Verify installation:

Terminal
mysql -u root -p
# Enter password when prompted
SHOW DATABASES;

Step 2: Create Database & Table

SQL
CREATE DATABASE college_db;
USE college_db;
CREATE TABLE books (
    book_id INT PRIMARY KEY AUTO_INCREMENT,
    title VARCHAR(100) NOT NULL,
    author VARCHAR(80),
    isbn VARCHAR(20) UNIQUE,
    price DECIMAL(8,2),
    copies INT DEFAULT 1
);
INSERT INTO books (title,author,isbn,price,copies)
  VALUES ('Let Us C','Yashavant Kanetkar','978-81-8333-163-0',350.00,8);

Step 3: Download MySQL Connector/J

Download mysql-connector-j-8.x.x.jar from dev.mysql.com/downloads/connector/j/. Place it in your project's lib/ folder.

Step 4: Write Your First JDBC Program

Create TestConnection.java:

Java
import java.sql.*;

public class TestConnection {
    public static void main(String[] args) {
        try (Connection conn = DriverManager.getConnection(
                "jdbc:mysql://localhost:3306/college_db", "root", "password")) {
            System.out.println("โœ… Connected to MySQL!");
            System.out.println("Database: " + conn.getCatalog());
        } catch (SQLException e) {
            System.out.println("โŒ Connection failed: " + e.getMessage());
        }
    }
}

Step 5: Compile & Run

Terminal
javac TestConnection.java
java -cp ".;lib/mysql-connector-j-8.0.33.jar" TestConnection
โœ… Connected to MySQL! Database: college_db

๐ŸŽ‰ Congratulations! You've established your first JDBC connection. This is the foundation for everything else in this unit.

๐ŸŸก Tier 2 โ€” SEMI-GUIDED: Build the Complete Library CRUD

โฑ๏ธ 90โ€“120 minutesIntermediateHints provided, you fill the gaps

Your Mission:

Build the full LibraryCRUD.java application from Section C (concept 12) with these additions:

  1. Add validation: Don't allow negative prices or zero copies
  2. Add a "Book Count" menu option using SELECT COUNT(*) FROM books
  3. Use try-with-resources for all connections and statements
  4. Add search by ISBN (exact match) in addition to keyword search

Hints:

  • For validation: check values BEFORE creating the PreparedStatement
  • For COUNT: rs.getInt(1) on a SELECT COUNT(*) query gives the count
  • For ISBN search: WHERE isbn = ? (exact match, not LIKE)
Stretch Goal: Add a generateReport() method that shows total books, total copies, average price, and most expensive book โ€” all using SQL aggregate functions (COUNT, SUM, AVG, MAX).

๐Ÿ”ด Tier 3 โ€” OPEN CHALLENGE: Student Marks System with Transactions

โฑ๏ธ 2โ€“3 hoursAdvancedNo handholding โ€” real-world mini-project

The Brief:

Build a complete Student Marks Entry & Report System with:

  1. Student Registration: Add student with ID, name, branch, semester
  2. Marks Entry: Enter marks for 5 subjects using batch processing
  3. Transaction Safety: If any marks entry fails, rollback student + all marks
  4. Report Card: Display marks, total, percentage, and pass/fail status
  5. Topper List: Show top 5 students by total marks using ORDER BY ... LIMIT 5
  6. Branch-wise Average: Use GROUP BY branch to show average marks per branch

Deliverable: A working Java program with MySQL backend. Include the SQL schema and at least 5 sample student records.

This exact system is what colleges need. Many small colleges in India still manage marks in Excel. A Java-MySQL marks management system can be sold for โ‚น15,000โ€“โ‚น30,000 per installation. Add a simple Swing GUI and the price doubles.
Section E

Problem Set โ€” Practice Questions

Syntax Questions (5)

  1. Write the JDBC URL format for connecting to a MySQL database named shopDB on localhost port 3306.
  2. Write a Java statement to create a PreparedStatement that inserts a record into table products(name, price).
  3. Write the code to set the 1st parameter of a PreparedStatement to the string "Laptop" and 2nd parameter to 45000.00.
  4. Write a while loop that reads all rows from a ResultSet and prints the name (String) and price (double) columns.
  5. Write the three lines needed to start a transaction, commit it, and rollback on failure.

Programming Questions (8)

  1. Write a complete Java program that connects to MySQL and creates a table employees(id INT PRIMARY KEY, name VARCHAR(50), salary DECIMAL(10,2)).
  2. Write a JDBC program to insert 3 employee records using batch processing.
  3. Write a program that takes an employee name from the user (Scanner) and searches the employees table using PreparedStatement with LIKE.
  4. Write a program that updates the salary of all employees in department "IT" by 10% using a single UPDATE statement.
  5. Write a program that deletes all employees with salary less than โ‚น15,000 and prints how many records were deleted.
  6. Write a program that uses DatabaseMetaData to print all table names in the current database.
  7. Write a program that transfers โ‚น5,000 from account A to account B using transaction management (debit A, credit B, commit/rollback).
  8. Write a program that reads data from the students table and writes it to a CSV file using ResultSet + FileWriter.

Industry-Scale Questions (3)

๐Ÿš‚ Industry Q1: IRCTC Booking Database

Design the database schema for a simplified IRCTC train booking system with tables: trains, passengers, bookings. Write JDBC code for:

  1. Searching available trains between two stations on a given date
  2. Booking a ticket (with transaction: check availability โ†’ insert booking โ†’ decrement seats)
  3. Cancelling a ticket (with transaction: delete booking โ†’ increment seats โ†’ process refund)

๐ŸŽ“ Industry Q2: EDUARTHA Marks Management System

Build a university marks management system with tables: students, courses, enrollments, marks. Implement:

  1. Batch insert of marks for an entire class (40 students ร— 5 subjects = 200 records)
  2. Generate a result sheet showing each student's marks, total, percentage, and grade
  3. Branch-wise topper report using GROUP BY and MAX

๐Ÿข Industry Q3: Inventory Management for Kirana Store

Design and implement a JDBC-based inventory management system for a local kirana (grocery) store. Include:

  1. Product CRUD with categories (dairy, grains, beverages, etc.)
  2. Stock alert: Query all products where quantity < reorder_level
  3. Daily sales recording with transaction (deduct stock + record sale)

Interview Questions (3)

  1. Infosys/TCS Interview: "What is the difference between Statement and PreparedStatement? Why is PreparedStatement preferred in production?" (Expected: mention SQL injection, performance, parameterisation)
  2. Wipro Interview: "Explain connection pooling. Why is creating a new connection for every request bad? Name one connection pool library." (Expected: mention HikariCP, overhead, resource exhaustion)
  3. Capgemini Interview: "What happens if you call conn.commit() when autoCommit is true? What is a dirty read?" (Expected: no-op for commit, explain isolation levels)
Section F

MCQ Assessment Bank โ€” 30 Questions (Bloom's Mapped)

Remember / Identify (Q1โ€“Q6)

Q1

JDBC stands for:

  1. Java Data Base Connection
  2. Java Database Connectivity
  3. Java Data Binding Connector
  4. Java Dynamic Base Controller
Remember
โœ… Answer: (B) Java Database Connectivity โ€” JDBC is a Java API that enables Java programs to execute SQL statements against any relational database.
Q2

Which package contains the core JDBC classes and interfaces?

  1. java.io
  2. java.sql
  3. javax.database
  4. java.jdbc
Remember
โœ… Answer: (B) java.sql โ€” This package contains Connection, Statement, ResultSet, DriverManager, PreparedStatement, and other core JDBC types.
Q3

Which method is used to establish a JDBC connection?

  1. Connection.open()
  2. DriverManager.getConnection()
  3. Database.connect()
  4. JDBC.createConnection()
Remember
โœ… Answer: (B) DriverManager.getConnection() โ€” Takes URL, username, and password as arguments and returns a Connection object.
Q4

The Type 4 JDBC driver is also known as:

  1. JDBC-ODBC Bridge
  2. Native-API Driver
  3. Network Protocol Driver
  4. Thin Driver (Pure Java)
Remember
โœ… Answer: (D) Thin Driver (Pure Java) โ€” Type 4 drivers are written entirely in Java, communicate directly with the database via its network protocol, and are the industry standard.
Q5

Which method moves the cursor to the next row in a ResultSet?

  1. advance()
  2. moveNext()
  3. next()
  4. forward()
Remember
โœ… Answer: (C) next() โ€” Returns true if there is a next row, false when the ResultSet is exhausted.
Q6

Which method is used to execute a SELECT query in JDBC?

  1. executeUpdate()
  2. executeQuery()
  3. execute()
  4. executeSelect()
Remember
โœ… Answer: (B) executeQuery() โ€” Returns a ResultSet. executeUpdate() is for INSERT/UPDATE/DELETE and returns an int (row count).

Understand / Explain (Q7โ€“Q12)

Q7

Why is PreparedStatement preferred over Statement for user-input queries?

  1. It is faster to type
  2. It prevents SQL injection by treating parameters as data, not SQL code
  3. It automatically creates the database table
  4. It does not require a Connection object
Understand
โœ… Answer: (B) โ€” PreparedStatement uses parameterised queries (?) that separate SQL structure from data. User input can never be interpreted as SQL commands, preventing injection attacks.
Q8

What does conn.setAutoCommit(false) do?

  1. Closes the connection
  2. Prevents any SQL from executing
  3. Starts manual transaction management โ€” changes are not saved until commit() is called
  4. Enables read-only mode
Understand
โœ… Answer: (C) โ€” By default, each SQL statement is auto-committed. Setting autoCommit to false lets you group multiple statements into a transaction, committing or rolling back as a unit.
Q9

What is the purpose of connection pooling?

  1. To encrypt database connections
  2. To reuse pre-created database connections instead of creating new ones for every request
  3. To merge multiple databases into one
  4. To backup the database automatically
Understand
โœ… Answer: (B) โ€” Connection pooling maintains a "pool" of open connections. Requests borrow and return connections, avoiding the expensive overhead of creating new connections (200โ€“500ms each).
Q10

Why was the Type 1 (JDBC-ODBC Bridge) driver removed in Java 8?

  1. It was too fast and unnecessary
  2. It was platform-dependent, slow, and not suitable for production use
  3. It was too secure
  4. It conflicted with Type 4 drivers
Understand
โœ… Answer: (B) โ€” The JDBC-ODBC Bridge depended on native ODBC drivers (Windows-only), was slow due to double translation (JDBCโ†’ODBCโ†’DB), and was never suitable for production applications.
Q11

What value does executeUpdate() return?

  1. A ResultSet
  2. A boolean
  3. The number of rows affected
  4. The auto-generated key
Understand
โœ… Answer: (C) โ€” executeUpdate() returns an int representing the number of rows inserted, updated, or deleted by the SQL statement.
Q12

What happens when rs.next() returns false?

  1. The program crashes
  2. It means there are no more rows to read in the ResultSet
  3. It means the connection is closed
  4. It means the query had an error
Understand
โœ… Answer: (B) โ€” When next() returns false, the cursor has moved past the last row. The while(rs.next()) loop naturally terminates.

Apply / Implement (Q13โ€“Q18)

Q13

Which code correctly inserts a record using PreparedStatement?

  1. pstmt.setString(0, "Amit");
  2. pstmt.setString(1, "Amit");
  3. pstmt.setString("name", "Amit");
  4. pstmt.addString(1, "Amit");
Apply
โœ… Answer: (B) โ€” PreparedStatement parameters are 1-indexed. setString(1, "Amit") sets the first ? placeholder to "Amit".
Q14

To execute INSERT INTO students VALUES (?, ?), which method should be called?

  1. executeQuery()
  2. executeUpdate()
  3. executeInsert()
  4. execute() only
Apply
โœ… Answer: (B) โ€” INSERT, UPDATE, and DELETE are DML statements that modify data. Use executeUpdate() which returns the number of affected rows.
Q15

Given ResultSet rs from a query on table employees(id INT, name VARCHAR, salary DOUBLE), which correctly reads the salary?

  1. rs.getString("salary")
  2. rs.getDouble("salary")
  3. rs.getInt("salary")
  4. rs.getFloat("salary")
Apply
โœ… Answer: (B) โ€” The salary column is DOUBLE, so getDouble("salary") is the correct type-matched getter.
Q16

What is the correct order to close JDBC resources?

  1. Connection โ†’ Statement โ†’ ResultSet
  2. ResultSet โ†’ Connection โ†’ Statement
  3. ResultSet โ†’ Statement โ†’ Connection
  4. Statement โ†’ ResultSet โ†’ Connection
Apply
โœ… Answer: (C) โ€” Close in reverse order of creation: ResultSet first, then Statement, then Connection. Or use try-with-resources for automatic closing.
Q17

Which code adds a SQL statement to a batch?

  1. pstmt.executeBatch();
  2. pstmt.addBatch();
  3. pstmt.batchAdd();
  4. pstmt.appendBatch();
Apply
โœ… Answer: (B) โ€” addBatch() adds the current set of parameters to the batch. After adding all, call executeBatch() to execute them all at once.
Q18

To get the number of tables in a database, which object do you use?

  1. ResultSet
  2. Statement
  3. DatabaseMetaData
  4. ConnectionInfo
Apply
โœ… Answer: (C) โ€” DatabaseMetaData provides metadata about the database: tables, columns, supported features, driver info, etc. Obtained via conn.getMetaData().

Analyze / Compare (Q19โ€“Q23)

Q19

A developer uses Statement with string concatenation to build SQL queries from user input. What is the primary risk?

  1. NullPointerException
  2. SQL injection attack
  3. ClassNotFoundException
  4. ArrayIndexOutOfBoundsException
Analyze
โœ… Answer: (B) โ€” String concatenation with user input allows attackers to inject malicious SQL (e.g., '; DROP TABLE students; --). Always use PreparedStatement.
Q20

An application creates a new Connection for every HTTP request and never closes them. What will happen over time?

  1. The application will run faster
  2. Database connections will exhaust, causing "Too many connections" error
  3. The database will automatically create more connections
  4. Nothing โ€” Java garbage collector handles connections
Analyze
โœ… Answer: (B) โ€” Databases have a maximum connection limit (e.g., MySQL default: 151). Unclosed connections accumulate until the limit is reached, then new connections fail. This is called a "connection leak."
Q21

Why does batch processing improve performance for bulk inserts?

  1. It uses a different database engine
  2. It reduces network round trips by sending multiple SQL statements in one batch
  3. It compresses the data
  4. It bypasses the SQL parser
Analyze
โœ… Answer: (B) โ€” Without batching, 1,000 inserts = 1,000 network round trips. With batching, 1,000 inserts = 1 network round trip. The DB also optimises batch execution internally.
Q22

In a bank transfer transaction (debit A, credit B), if the credit to B fails, what should happen to the debit from A?

  1. It should remain โ€” partial transactions are fine
  2. It should be rolled back โ€” the entire transaction must be atomic
  3. It should be logged and manually fixed later
  4. It should be committed separately
Analyze
โœ… Answer: (B) โ€” Atomicity (the "A" in ACID) requires that either ALL operations in a transaction succeed, or NONE do. Rollback undoes the debit, keeping the database consistent.
Q23

Compare: a CachedRowSet fetches all data and disconnects. A JdbcRowSet stays connected. Which is better for a mobile app with intermittent connectivity?

  1. JdbcRowSet โ€” it maintains real-time data
  2. CachedRowSet โ€” it works offline after initial fetch
  3. Neither โ€” use Statement instead
  4. Both are identical in behaviour
Analyze
โœ… Answer: (B) โ€” CachedRowSet fetches data into memory and disconnects. The app can work with data even when offline, then sync changes when reconnected. Ideal for unreliable networks.

Evaluate / Assess (Q24โ€“Q27)

Q24

A developer writes: String sql = "DELETE FROM users WHERE id = " + userId; and passes it to stmt.execute(sql). Evaluate this code.

  1. It is correct and efficient
  2. It works but is vulnerable to SQL injection โ€” should use PreparedStatement
  3. It will throw a compilation error
  4. It is the recommended approach for DELETE operations
Evaluate
โœ… Answer: (B) โ€” The code technically works for valid integers, but if userId comes from user input, an attacker could inject "1 OR 1=1" to delete ALL users. PreparedStatement eliminates this risk.
Q25

Assess: Should autoCommit be set to false for a simple single-row SELECT query?

  1. Yes โ€” always disable autoCommit
  2. No โ€” single read-only queries don't need manual transaction control
  3. Yes โ€” it improves performance
  4. No โ€” autoCommit(false) disables SELECT queries
Evaluate
โœ… Answer: (B) โ€” Manual transaction management adds complexity. For simple read-only operations, autoCommit=true (default) is fine. Use manual transactions only when multiple related DML operations must succeed or fail together.
Q26

A team uses DriverManager.getConnection() in every method of their web application (50+ methods). Evaluate this approach.

  1. It's the correct approach โ€” each method needs its own connection
  2. It's inefficient โ€” they should use connection pooling (e.g., HikariCP)
  3. It's fine โ€” Java automatically pools connections from DriverManager
  4. It's wrong โ€” only one connection should exist per application
Evaluate
โœ… Answer: (B) โ€” DriverManager creates a NEW connection each time (200โ€“500ms). For web apps with concurrent users, this causes resource exhaustion. Connection pooling reuses connections efficiently.
Q27

Is it acceptable to store database credentials (username/password) directly in the Java source code?

  1. Yes โ€” it makes deployment easier
  2. No โ€” credentials should be in external config files or environment variables
  3. Yes โ€” if the code is not open-source
  4. No โ€” Java doesn't allow string literals for passwords
Evaluate
โœ… Answer: (B) โ€” Hardcoded credentials in source code are a major security risk. If the code is committed to Git, anyone with repo access sees the password. Use environment variables, .properties files, or secret managers.

Create / Design (Q28โ€“Q30)

Q28

You need to design a JDBC-based system that inserts 10,000 student records from a CSV file. Which approach is best?

  1. 10,000 individual executeUpdate() calls
  2. PreparedStatement with addBatch() + executeBatch() inside a transaction
  3. Use Statement with string concatenation for each row
  4. Create 10,000 separate Connection objects
Create
โœ… Answer: (B) โ€” Batch processing with PreparedStatement is the optimal approach: fewer network round trips, pre-compiled SQL, and wrapping in a transaction ensures atomicity. This is how Infosys/TCS handle bulk data migrations.
Q29

You're designing a library management system. Which JDBC feature ensures that when a book is issued, both "decrement copies" and "insert issue record" succeed or both fail?

  1. Batch processing
  2. Transaction management (setAutoCommit, commit, rollback)
  3. Connection pooling
  4. DatabaseMetaData
Create
โœ… Answer: (B) โ€” Transaction management ensures atomicity. setAutoCommit(false) โ†’ execute both operations โ†’ commit(). If either fails, rollback() undoes both, keeping data consistent.
Q30

You need to build a reporting module that queries a large database but must work even when the network disconnects mid-session. Which JDBC component fits best?

  1. Statement
  2. PreparedStatement
  3. CachedRowSet
  4. CallableStatement
Create
โœ… Answer: (C) โ€” CachedRowSet is a disconnected RowSet. It fetches all data into memory, closes the connection, and allows offline access. Perfect for unreliable network environments or mobile apps.
Section G

Short Answer Questions (8)

Q1. What is JDBC? What are the main components of the JDBC API?

Answer: JDBC (Java Database Connectivity) is a Java API that enables Java applications to interact with relational databases. It provides a standard interface for connecting to databases, executing SQL statements, and processing results.

Main components:

  • DriverManager: Manages a list of database drivers and establishes connections
  • Connection: Represents an active database session
  • Statement / PreparedStatement / CallableStatement: Executes SQL queries
  • ResultSet: Holds the data returned by a SELECT query

Q2. Differentiate between Statement and PreparedStatement.

Statement: Executes static SQL strings. The SQL is parsed and compiled every time. Vulnerable to SQL injection when user input is concatenated into the query string.

PreparedStatement: Executes parameterised SQL with ? placeholders. Pre-compiled once and reused with different parameter values. Safe from SQL injection because parameters are treated as data, not SQL code. Also faster for repeated executions due to cached execution plans.

Rule: Always use PreparedStatement for any query involving user input.

Q3. List and explain the four types of JDBC drivers.

Type 1 (JDBC-ODBC Bridge): Translates JDBC calls to ODBC calls. Platform-dependent. Removed in Java 8.

Type 2 (Native-API): Uses database vendor's native client library. Faster than Type 1 but still platform-dependent.

Type 3 (Network Protocol): Sends JDBC calls to a middleware server that translates and forwards to the database. Adds an extra network hop.

Type 4 (Thin/Pure Java): Communicates directly with the database using the DB's network protocol. 100% Java, platform-independent, fastest. Industry standard (e.g., MySQL Connector/J, PostgreSQL JDBC).

Q4. What is SQL injection? How does PreparedStatement prevent it?

SQL Injection: A security attack where an attacker inserts malicious SQL code into user input fields. If the application uses string concatenation to build SQL queries, the injected code executes as part of the SQL statement, potentially dropping tables, stealing data, or bypassing authentication.

Prevention by PreparedStatement: PreparedStatement separates the SQL structure from the data. The SQL template (SELECT * FROM users WHERE name = ?) is compiled first. User input is then bound to the ? placeholder as a data value โ€” it can never be interpreted as SQL code, even if it contains SQL keywords or special characters.

Q5. Explain transaction management in JDBC with an example.

Transaction management ensures that a group of related database operations either ALL succeed (commit) or ALL fail (rollback), maintaining data consistency.

Steps:

  1. conn.setAutoCommit(false) โ€” Disable automatic commit
  2. Execute multiple SQL statements
  3. conn.commit() โ€” Save all changes if everything succeeds
  4. conn.rollback() โ€” Undo all changes if any operation fails (in catch block)

Example: Transferring โ‚น5,000 from Account A to Account B requires two operations: debit A and credit B. If the credit fails after the debit, rollback ensures A's money is restored.

Q6. What is connection pooling? Why is it important?

Connection pooling maintains a pool of pre-created database connections that can be reused across multiple requests. Instead of creating a new connection for each request (expensive: 200โ€“500ms), applications borrow a connection from the pool and return it when done.

Importance: In a web application handling 1,000 requests/second, creating 1,000 new connections would overwhelm the database. A pool of 20โ€“50 connections serves all 1,000 requests efficiently. HikariCP is the most popular Java connection pool library and is the default in Spring Boot.

Q7. What is the difference between executeQuery() and executeUpdate()?

executeQuery(): Used for SELECT statements. Returns a ResultSet containing the rows returned by the query.

executeUpdate(): Used for INSERT, UPDATE, DELETE, and DDL (CREATE, ALTER, DROP) statements. Returns an int indicating the number of rows affected.

execute(): Can be used for any SQL statement. Returns a boolean โ€” true if the result is a ResultSet, false if it's an update count.

Q8. What is a RowSet? How does CachedRowSet differ from ResultSet?

RowSet: A wrapper interface around ResultSet (from javax.sql package) that adds JavaBeans support, scrollability, and disconnected operation.

CachedRowSet vs ResultSet:

  • ResultSet requires an active Connection โ€” if the connection closes, the ResultSet becomes invalid
  • CachedRowSet fetches all data into memory and disconnects โ€” works offline, serialisable, can be passed between layers
  • CachedRowSet can also sync changes back to the database when reconnected using acceptChanges()
Section H

Long Answer Questions (3)

Q1. Explain the JDBC architecture in detail with a diagram. Describe the role of each component and how data flows from a Java application to the database and back. (10 marks)

Model Answer:

JDBC follows a 4-tier architecture:

Tier 1 โ€” Java Application: The developer writes Java code that uses the JDBC API. This could be a standalone app, a servlet, or a Spring Boot service. The application creates SQL queries, sets parameters, and processes results.

Tier 2 โ€” JDBC API (java.sql / javax.sql): This layer provides standard interfaces (Connection, Statement, PreparedStatement, ResultSet, etc.) that define what operations are possible. The API acts as a contract โ€” the application codes against these interfaces without knowing the specific database being used.

Tier 3 โ€” JDBC Driver: The DriverManager class maintains a registry of available drivers. When getConnection(url) is called, it matches the URL pattern to the correct driver. The driver (e.g., mysql-connector-j.jar) implements the JDBC interfaces and translates JDBC calls into the database's native protocol (e.g., MySQL Protocol over TCP/IP).

Tier 4 โ€” Database: The actual database server (MySQL, Oracle, PostgreSQL) receives the translated commands, parses the SQL, executes it against stored data, and returns results through the same chain in reverse.

Data Flow: Application โ†’ JDBC API โ†’ Driver โ†’ Network โ†’ Database โ†’ Results โ†’ Driver โ†’ JDBC API โ†’ Application (ResultSet)

This layered architecture provides database independence โ€” changing from MySQL to PostgreSQL requires only changing the driver JAR and connection URL, not the application code.

Q2. Write a complete Java JDBC program that performs all CRUD operations on an Employee table. Explain each operation with proper exception handling and resource management. (15 marks)

Model Answer: The program should include:

  1. CREATE (INSERT): Use PreparedStatement with setString/setInt/setDouble to insert employee records. Use try-with-resources for automatic resource cleanup.
  2. READ (SELECT): Execute a parameterised SELECT query. Iterate through ResultSet using while(rs.next()) and extract values using getInt/getString/getDouble with column names.
  3. UPDATE: Use PreparedStatement with SET clause and WHERE condition. Call executeUpdate() which returns the count of modified rows.
  4. DELETE: Use PreparedStatement with WHERE clause. Verify affected rows count to confirm deletion.

Key points for full marks:

  • Use try-with-resources (not manual close)
  • Use PreparedStatement (not Statement)
  • Proper SQLException handling with meaningful error messages
  • Close resources in correct order (ResultSet โ†’ Statement โ†’ Connection)
  • Use parameterised queries to prevent SQL injection

(Full code provided in Section C, Concept 6 โ€” reference the InsertBook, SelectBooks, UpdateBook, DeleteBook programs)

Q3. Explain transaction management in JDBC. Write a program that demonstrates commit and rollback with a real-world example of a bank fund transfer. What are ACID properties? (12 marks)

Model Answer:

Transaction Management ensures a group of database operations are treated as a single atomic unit. Either all operations succeed (commit) or all are undone (rollback).

ACID Properties:

  • Atomicity: All operations in a transaction complete successfully, or none do
  • Consistency: Database moves from one valid state to another โ€” no constraint violations
  • Isolation: Concurrent transactions don't interfere with each other
  • Durability: Once committed, changes survive system crashes

JDBC Implementation Steps:

  1. conn.setAutoCommit(false) โ€” Start manual transaction control
  2. Execute SQL statements (debit from Account A, credit to Account B)
  3. conn.commit() โ€” Persist changes if all operations succeed
  4. In catch block: conn.rollback() โ€” Undo all changes if any operation fails
  5. In finally block: conn.setAutoCommit(true) โ€” Restore default behaviour

Real-world importance: Without transactions, a bank transfer could debit โ‚น10,000 from your account but fail to credit the recipient โ€” losing money. IRCTC uses transactions to ensure ticket booking (seat allocation + payment deduction + PNR generation) is atomic.

(Full code provided in Section C, Concept 7 โ€” reference the IssueBookTransaction program)

Section I

Lab Exercises

All lab exercises for this unit are covered in Section D (Learn by Doing) with the 3-Tier lab structure:

TierExerciseDurationDifficulty
๐ŸŸข Tier 1Setup MySQL + First JDBC Connection60โ€“90 minBeginner
๐ŸŸก Tier 2Complete Library CRUD Application90โ€“120 minIntermediate
๐Ÿ”ด Tier 3Student Marks System with Transactions2โ€“3 hoursAdvanced

Refer to Section D for detailed instructions, hints, and stretch goals for each tier.

Section J

Industry Spotlight โ€” A Day in the Life

๐Ÿ‘จโ€๐Ÿ’ป Suresh Patel, 31 โ€” Senior Java Developer at Infosys, Pune

Background: B.Tech from a Tier-3 college in Gujarat. No campus placement. Self-taught Java and JDBC through YouTube and free courses. Built a hospital billing system as a college project using Java + MySQL. Joined Infosys as a fresher through off-campus drive. Now leads a team of 8 developers working on a banking middleware project.

A Typical Day:

9:00 AM โ€” Standup call with the banking client (SBI). Review JIRA tickets โ€” today's focus: optimize a slow JDBC query that takes 4 seconds to load 50,000 transaction records.

10:00 AM โ€” Profile the slow query. Discover the developer used Statement instead of PreparedStatement โ€” query is being re-parsed on every call. Switch to PreparedStatement: response time drops to 800ms.

11:30 AM โ€” Code review for a junior developer's module. Find an open Connection that's never closed โ€” classic connection leak. Add try-with-resources and explain the pattern.

1:00 PM โ€” Lunch in Infosys cafeteria. Discuss HikariCP connection pool tuning with a colleague โ€” they're seeing "Connection pool exhausted" errors under peak load.

2:30 PM โ€” Implement a new feature: batch processing for bulk salary credits. Process 10,000 salary records using addBatch() + executeBatch() with transaction management. If any credit fails, entire batch rolls back.

4:00 PM โ€” Write JUnit tests for the JDBC DAO layer. Mock the Connection using Mockito. Achieve 85% code coverage.

5:30 PM โ€” Deploy to staging environment. Run integration tests against a test Oracle database. All green. Push for QA review.

DetailInfo
Tools Used DailyJava 17, JDBC, HikariCP, Oracle DB, Spring Boot, Maven, JUnit, Git
Entry Salary (2024)โ‚น3.6โ€“4.5 LPA (Infosys System Engineer)
Mid-Level (4โ€“6 yrs)โ‚น8โ€“15 LPA (Technology Lead)
Senior (8+ yrs)โ‚น18โ€“30 LPA (Technical Architect)
Companies HiringInfosys, TCS, Wipro, HCL, Cognizant, Capgemini, Oracle India, IBM India, Accenture
Key Advice"Master JDBC before jumping to JPA/Hibernate. Every ORM generates JDBC calls underneath. If you understand JDBC, debugging ORM issues becomes 10x easier."
Section K

Earn With It โ€” Freelance & Income Roadmap

๐Ÿ’ฐ Your Earning Path After This Unit โ€” โ‚น10Kโ€“โ‚น40K/month

What you can build: JDBC CRUD applications for small and medium businesses โ€” inventory systems, billing apps, attendance trackers, library management, student record systems, clinic patient databases.

Why businesses pay: Most small Indian businesses still use pen-and-paper or Excel. A proper database application with search, reports, and backup is worth โ‚น10,000โ€“โ‚น40,000 to them.

Gig TypeClientPrice RangeTime to Build
Inventory Management SystemKirana store, medical shop, hardware shopโ‚น10,000โ€“โ‚น20,0001โ€“2 weeks
Billing / Invoice AppFreelancers, small traders, service providersโ‚น8,000โ€“โ‚น15,0005โ€“7 days
Attendance TrackerCoaching centres, small offices, gymsโ‚น5,000โ€“โ‚น12,0003โ€“5 days
Library Management SystemSchool libraries, college departmentsโ‚น10,000โ€“โ‚น25,0001โ€“2 weeks
Student Records DatabaseCoaching centres, tuition classesโ‚น8,000โ€“โ‚น20,0001 week
Clinic Patient DatabaseSmall clinics, dentists, physiotherapy centresโ‚น15,000โ€“โ‚น40,0002โ€“3 weeks
Pro tip: Add a simple Swing GUI and charge 2ร— more. A command-line CRUD app is worth โ‚น10K. The same app with a clean Swing/JavaFX GUI is worth โ‚น20Kโ€“โ‚น30K. Businesses want something they can "click" โ€” they don't want to type commands in a terminal. Learn Java Swing basics (JFrame, JTable, JButton) and your earning potential doubles overnight.
PlatformBest ForTypical Rate
InternshalaFirst freelance projects, college-level clientsโ‚น5,000โ€“โ‚น15,000/project
FiverrGlobal clients, quick Java/DB gigs$30โ€“$100/gig (โ‚น2,500โ€“โ‚น8,000)
UpworkSerious long-term clients$15โ€“$50/hour
Local WhatsApp/LinkedInDirect outreach to local businessesโ‚น10,000โ€“โ‚น40,000/project

โฑ๏ธ Time to First Earning: 3โ€“4 weeks (if you complete all 3 lab tiers and pitch to 10 local businesses)

The money is in MAINTENANCE, not just building. Charge โ‚น1,000โ€“โ‚น3,000/month for ongoing maintenance (backups, bug fixes, small feature additions). 10 clients ร— โ‚น2,000/month = โ‚น20,000/month recurring income while still in college.
Section L

Chapter Summary

๐Ÿ“‹ Unit 14 โ€” JDBC Database Programming: Key Takeaways

  • JDBC = Java Database Connectivity โ€” the standard API for Java programs to talk to relational databases
  • 4-Tier Architecture: Application โ†’ JDBC API โ†’ Driver โ†’ Database
  • 5-Step Workflow: Load Driver โ†’ Get Connection โ†’ Create Statement โ†’ Execute โ†’ Process Results โ†’ Close
  • 4 Driver Types: Type 1 (ODBC Bridge, obsolete), Type 2 (Native), Type 3 (Network), Type 4 (Pure Java โ€” use this!)
  • 3 Statement Types: Statement (static, vulnerable), PreparedStatement (parameterised, safe), CallableStatement (stored procedures)
  • CRUD: INSERT (executeUpdate), SELECT (executeQuery + ResultSet), UPDATE (executeUpdate), DELETE (executeUpdate)
  • Transactions: setAutoCommit(false) โ†’ operations โ†’ commit() / rollback() โ€” ensures ACID properties
  • Batch Processing: addBatch() + executeBatch() โ€” essential for bulk operations
  • Connection Pooling: HikariCP โ€” reuse pre-created connections, avoid per-request overhead
  • Security: ALWAYS use PreparedStatement. NEVER concatenate user input into SQL strings.

๐Ÿฆ Code Tweet โ€” Entire JDBC in 280 Characters

Java โ€” JDBC in a tweet
// JDBC in 5 lines:
Connection c = DriverManager.getConnection(url,u,p);
PreparedStatement ps = c.prepareStatement("SELECT * FROM t WHERE id=?");
ps.setInt(1,42);
ResultSet rs = ps.executeQuery();
while(rs.next()) out.println(rs.getString(1));
// That's it. Javaโ†’SQLโ†’DBโ†’Results. ๐Ÿš€
Section M

Earning Checkpoint

Skill LearnedTool / TechniquePortfolio PieceEarn-Ready?
JDBC ConnectionDriverManager, ConnectionTestConnection.javaโฌœ Foundation skill
CRUD OperationsPreparedStatement, ResultSetLibraryCRUD.javaโœ… Yes โ€” โ‚น10Kโ€“โ‚น25K/project
Transaction Managementcommit(), rollback()IssueBookTransaction.javaโœ… Yes โ€” critical for billing apps
Batch ProcessingaddBatch(), executeBatch()Bulk student importโœ… Yes โ€” data migration gigs
SQL Injection PreventionPreparedStatementSecure coding knowledgeโœ… Yes โ€” interview-ready
Connection PoolingHikariCP (concept)โ€”โฌœ Need Spring Boot practice
Full ApplicationJava + MySQL + CRUDStudent Marks Systemโœ… Yes โ€” โ‚น15Kโ€“โ‚น40K/project
Minimum Viable Earning Setup after this unit: A working LibraryCRUD.java + StudentMarksSystem.java in your GitHub portfolio + an Internshala/LinkedIn profile listing "Java MySQL Developer" = you can start earning โ‚น10,000โ€“โ‚น40,000/month from CRUD application gigs for local businesses.

โœ… Unit 14 complete. MCQs: 30. Ready for Unit 15: Capstone!

[QR: Link to EduArtha video tutorial โ€” JDBC Database Programming]