Advanced Java ProgrammingUnit 512 min read
JDBC: Architecture, Drivers, Statements & Database Operations
Unit 5 of Advanced Java Programming covers JDBC fundamentals—architecture, driver types, connection management, SQL execution via statements (prepared/batched), transaction handling, and result set processing—with practical examples for CRUD operations, error handling, and performance optimization.
Core Concepts
1. JDBC Overview
Java Database Connectivity (JDBC) is an API (Application Programming Interface) that enables Java programs to interact with relational databases. It provides a standardized way to execute SQL queries, process results, and manage transactions.
Key Components
classDiagram
class JDBC_API {
+DriverManager
+Connection
+Statement
+PreparedStatement
+CallableStatement
+ResultSet
+ResultSetMetaData
}
class Database {
<<Database>>
MySQL, Oracle, PostgreSQL
}
JDBC_API --> DriverManager : "Manages drivers"
DriverManager --> Connection : "Creates connections"
Connection --> Statement : "Creates statements"
Statement --> ResultSet : "Executes queries"How JDBC Works
- Load JDBC Driver: Register the database driver (e.g.,
com.mysql.jdbc.Driver). - Establish Connection: Use
DriverManager.getConnection()with URL, username, and password. - Create Statement: Generate
Statement,PreparedStatement, orCallableStatement. - Execute Query: Call
executeQuery(),executeUpdate(), orexecute(). - Process Results: Handle
ResultSetor check affected rows. - Close Resources: Release connections, statements, and result sets.
2. JDBC Driver Types
JDBC supports four types of drivers, each with trade-offs in performance, compatibility, and setup complexity.
| Type | Description | Pros | Cons | Example |
|---|---|---|---|---|
| Type 1 | JDBC-ODBC Bridge (Deprecated) | Simple setup | Slow, outdated | sun.jdbc.odbc.JdbcOdbcDriver |
| Type 2 | Native-API Driver (Vendor-specific) | Faster than Type 1 | Requires native libraries | Oracle Thin Driver |
| Type 3 | Network Protocol Driver (Middleware) | Database-independent | Adds network layer overhead | JDBC-ODBC Bridge (Type 1) |
| Type 4 | Pure Java Driver (Recommended) | Pure Java, no native code | Best performance for Java apps | com.mysql.cj.jdbc.Driver |
Exam Tip: Type 4 drivers (e.g., MySQL Connector/J, Oracle JDBC Thin) are preferred in modern applications due to their pure Java implementation and performance.
3. JDBC Statements
JDBC provides three types of statements for SQL execution:
a) Statement Interface
- Used for dynamic SQL queries (e.g.,
SELECT * FROM TABLE). - Vulnerable to SQL injection if user input is directly concatenated.
- Example:
Statement stmt = conn.createStatement(); ResultSet rs = stmt.executeQuery("SELECT * FROM MOVIE");
b) PreparedStatement Interface
- Precompiled SQL template with placeholders (
?) for parameters. - Prevents SQL injection and improves performance for repeated queries.
- Example:
PreparedStatement pstmt = conn.prepareStatement( "UPDATE MOVIE SET genre = ? WHERE title = ?"); pstmt.setString(1, "Comedy"); pstmt.setString(2, "Jatra"); pstmt.executeUpdate();
c) CallableStatement Interface
- Used for stored procedures (e.g.,
CALL procedure_name(?)). - Supports IN, OUT, and INOUT parameters.
- Example:
CallableStatement cstmt = conn.prepareCall("{CALL get_movie_count(?)}"); cstmt.setInt(1, 1); // Genre ID ResultSet rs = cstmt.executeQuery();
Comparison Table:
| Feature | Statement |
PreparedStatement |
CallableStatement |
|---|---|---|---|
| SQL Injection Risk | High | Low | Low |
| Performance | Low (per-query) | High (cached) | High (cached) |
| Use Case | Simple queries | Parameterized queries | Stored procedures |
4. ResultSet and Metadata
a) ResultSet
- Holds query results in a table-like structure.
- Types:
- TYPE_FORWARD_ONLY: Default (read-only, forward-only).
- TYPE_SCROLL_INSENSITIVE: Scrollable but not sensitive to changes.
- TYPE_SCROLL_SENSITIVE: Scrollable and sensitive to changes.
- Concurrency:
- CONCUR_READ_ONLY: Default (read-only).
- CONCUR_UPDATABLE: Allows updates/deletes.
Example: Scrollable ResultSet
Statement stmt = conn.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.executeQuery("SELECT * FROM TEACHER");
rs.last(); // Move to last row
System.out.println("Last record: " + rs.getString("Name"));
b) ResultSetMetaData
- Provides schema information (column names, types, sizes).
- Example:
ResultSetMetaData meta = rs.getMetaData(); int columns = meta.getColumnCount(); for (int i = 1; i <= columns; i++) { System.out.println("Column " + i + ": " + meta.getColumnName(i)); }
5. Transaction Management
JDBC supports ACID transactions (Atomicity, Consistency, Isolation, Durability).
- Methods:
conn.setAutoCommit(false): Disable auto-commit.conn.commit(): Save changes.conn.rollback(): Undo changes.conn.setTransactionIsolation(level): Set isolation level (e.g.,TRANSACTION_READ_COMMITTED).
Example: Transaction Handling
conn.setAutoCommit(false);
try {
PreparedStatement pstmt = conn.prepareStatement(
"UPDATE ACCOUNT SET balance = balance - ? WHERE id = ?");
pstmt.setDouble(1, 100.0);
pstmt.setInt(2, 1);
pstmt.executeUpdate();
pstmt = conn.prepareStatement(
"UPDATE ACCOUNT SET balance = balance + ? WHERE id = ?");
pstmt.setDouble(1, 100.0);
pstmt.setInt(2, 2);
pstmt.executeUpdate();
conn.commit();
} catch (SQLException e) {
conn.rollback();
e.printStackTrace();
} finally {
conn.setAutoCommit(true);
}
6. Batch Processing
- Improves performance by grouping multiple SQL statements into a single batch.
- Methods:
addBatch(String sql): Add a query to the batch.executeBatch(): Execute all batched queries.
- Example:
Statement stmt = conn.createStatement(); stmt.addBatch("INSERT INTO MOVIE VALUES (1, 'Jatra', 'Comedy')"); stmt.addBatch("INSERT INTO MOVIE VALUES (2, 'Alamchi', 'Drama')"); stmt.addBatch("INSERT INTO MOVIE VALUES (3, 'Sipahi', 'Action')"); int[] counts = stmt.executeBatch(); // Returns affected rows per query
7. Error Handling
- SQLException: Thrown for database errors (e.g., syntax errors, connection failures).
- Best Practices:
- Use
try-catch-finallyto close resources. - Log errors for debugging.
- Example:
try { conn = DriverManager.getConnection(url, user, password); } catch (SQLException e) { System.err.println("Connection failed: " + e.getMessage()); } finally { if (conn != null) try { conn.close(); } catch (SQLException e) { /* Log */ } }
- Use
8. Worked Examples
Example 1: Insert Records into MOVIE Table
String url = "jdbc:mysql://localhost:3306/mydb";
String user = "root";
String password = "password";
try (Connection conn = DriverManager.getConnection(url, user, password)) {
String[] titles = {"Jatra", "Alamchi", "Sipahi"};
String[] genres = {"Comedy", "Drama", "Action"};
for (int i = 0; i < titles.length; i++) {
PreparedStatement pstmt = conn.prepareStatement(
"INSERT INTO MOVIE (title, genre) VALUES (?, ?)");
pstmt.setString(1, titles[i]);
pstmt.setString(2, genres[i]);
pstmt.executeUpdate();
}
} catch (SQLException e) {
e.printStackTrace();
}
Example 2: Update Genre Using PreparedStatement
try (Connection conn = DriverManager.getConnection(url, user, password)) {
PreparedStatement pstmt = conn.prepareStatement(
"UPDATE MOVIE SET genre = ? WHERE title = ?");
pstmt.setString(1, "Comedy");
pstmt.setString(2, "Jatra");
int rowsAffected = pstmt.executeUpdate();
System.out.println("Updated " + rowsAffected + " rows.");
} catch (SQLException e) {
e.printStackTrace();
}
Example 3: Fetch and Display TEACHER Records
try (Connection conn = DriverManager.getConnection(url, user, password)) {
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM TEACHER");
while (rs.next()) {
int id = rs.getInt("ID");
String name = rs.getString("Name");
System.out.println("ID: " + id + ", Name: " + name);
}
} catch (SQLException e) {
e.printStackTrace();
}
Example 4: Insert into TEACHER Table
try (Connection conn = DriverManager.getConnection(url, user, password)) {
PreparedStatement pstmt = conn.prepareStatement(
"INSERT INTO TEACHER VALUES (?, ?)");
pstmt.setInt(1, 8);
pstmt.setString(2, "Ramesh");
pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
9. Best Practices
- Use
try-with-resources: Automatically closesConnection,Statement, andResultSet. - Prefer
PreparedStatement: Avoids SQL injection and improves performance. - Close Resources in
finally: Ensures no resource leaks. - Use Connection Pooling: For production apps (e.g., HikariCP, Apache DBCP).
- Handle Transactions Properly: Use
commit()/rollback()for critical operations. - Validate Inputs: Always sanitize user inputs before using in SQL.
10. Common Pitfalls
- Forgetting to close resources: Leads to memory leaks.
- SQL Injection: Using
Statementwith user input (e.g.,WHERE id = " + userInput). - Not handling transactions: Risk of partial updates.
- Ignoring exceptions: Silent failures can corrupt data.
Exam Tip
What Examiners Look For
- Correct Driver Loading: Ensure the driver is registered or loaded via
Class.forName()(though modern JDBC usesServiceLoader). - Proper Connection Handling: Use
try-with-resourcesorfinallyblocks to close connections. - Statement Selection:
- Use
PreparedStatementfor dynamic queries (avoids SQL injection). - Use
CallableStatementfor stored procedures.
- Use
- ResultSet Processing:
- Check
rs.next()before accessing data. - Use
ResultSetMetaDatafor column details if required.
- Check
- Transaction Management:
- Disable auto-commit for multi-step operations.
- Always
commit()orrollback().
- Batch Processing: Use
addBatch()for bulk operations. - Error Handling: Catch
SQLExceptionand handle gracefully.
Common Exam Questions & How to Answer
| Question Type | Key Points to Include |
|---|---|
| Differentiate JDBC driver types | Table with pros/cons + examples (Type 4 is most common). |
| PreparedStatement vs. Statement | SQL injection risk, performance, syntax (placeholders ?). |
| Scrollable ResultSet | Types (TYPE_SCROLL_INSENSITIVE), methods (last(), previous()), use cases. |
| Transaction management | setAutoCommit(false), commit(), rollback(), isolation levels. |
| Batch processing | addBatch(), executeBatch(), performance benefits. |
| CRUD operations | Code snippets for INSERT, UPDATE, SELECT, DELETE with PreparedStatement. |
| Error handling | try-catch-finally, logging, resource cleanup. |
Model Answer Structure
For practical questions (e.g., "Write JDBC code to insert 3 records into MOVIE"):
- Driver Loading:
Class.forName()or service loader (if required). - Connection:
DriverManager.getConnection()with URL, username, password. - Statement: Use
PreparedStatementfor safety. - Execution: Loop or batch for multiple records.
- Closure:
try-with-resourcesor manualclose(). - Error Handling:
catch (SQLException e) { e.printStackTrace(); }.
For theoretical questions (e.g., "Explain JDBC driver types"):
- Define each type in a table.
- Compare pros/cons.
- State which is most commonly used (Type 4).
- Give an example driver class (e.g.,
com.mysql.cj.jdbc.Driver).
flowchart TD
A[JDBC API] --> B[DriverManager]
B --> C[Load Driver]
C --> D[Get Connection]
D --> E[Create Statement]
E --> F[Execute Query]
F --> G[Process ResultSet]
G --> H[Close Resources]
H -->|Error| I[SQLException Handling]
H -->|Success| J[Transaction Commit/Rollback]Based on the TU BSc CSIT syllabus for Advanced Java Programming (CSC409), unit 5.
Discussion
Loading…