Top Interview Questions
JDBC (Java Database Connectivity) is a Java-based API that enables Java applications to interact with relational databases. It provides a standard interface for executing SQL queries, retrieving results, and managing database connections. JDBC acts as a bridge between Java applications and databases, allowing developers to write database-independent code for CRUD operations (Create, Read, Update, Delete).
JDBC is part of the Java Standard Edition (Java SE) platform and supports multiple database systems such as Oracle, MySQL, PostgreSQL, SQL Server, and IBM DB2. By using JDBC, Java applications can communicate with databases in a platform-independent manner, leveraging SQL to perform operations on data.
In enterprise applications, database connectivity is crucial for storing, retrieving, and manipulating data. JDBC provides:
Database Independence: JDBC allows developers to write Java programs without worrying about the underlying database system. Switching databases only requires changing the driver.
Standardized API: JDBC offers a uniform API to execute SQL queries and manage results, reducing the learning curve for developers.
Seamless Integration: Integrates easily with other Java technologies like JSP, Servlets, Spring, and Hibernate.
Flexibility: Supports dynamic SQL, prepared statements, and stored procedures for robust database operations.
Database Connectivity: Connects Java applications to any relational database using JDBC drivers.
SQL Execution: Supports executing SQL commands such as SELECT, INSERT, UPDATE, DELETE, and CREATE TABLE.
Result Set Handling: Provides ResultSet objects to navigate and manipulate query results efficiently.
Transaction Management: Supports transactions, allowing commit and rollback to maintain data integrity.
Batch Processing: Executes multiple SQL statements in a single batch to improve performance.
Metadata Access: Offers DatabaseMetaData and ResultSetMetaData to retrieve database and result set information.
Exception Handling: JDBC exceptions are managed using SQLException for robust error handling.
JDBC follows a multi-tier architecture that separates the Java application, JDBC API, driver management, and database system. Its architecture includes the following layers:
This is where the client application resides.
Developers write JDBC code in Java to perform database operations.
The API provides classes and interfaces such as Connection, Statement, PreparedStatement, and ResultSet.
Abstracts database operations, making the Java code database-independent.
Manages a list of database drivers and establishes connections to databases.
Handles communication between the Java application and the driver.
Converts JDBC API calls into database-specific calls.
There are four types of JDBC drivers:
Type 1: JDBC-ODBC bridge driver.
Type 2: Native API driver.
Type 3: Network protocol driver.
Type 4: Pure Java driver (most commonly used today).
The actual database system (Oracle, MySQL, SQL Server, PostgreSQL) processes SQL queries and returns results.
Manages a list of database drivers.
Establishes a connection to the database using DriverManager.getConnection(url, username, password).
Represents a session with a specific database.
Provides methods for creating Statement, PreparedStatement, and managing transactions.
Used to execute static SQL queries.
Supports three types: Statement, PreparedStatement, and CallableStatement.
Allows execution of parameterized queries.
Improves performance and prevents SQL injection attacks.
Used to execute stored procedures in the database.
Represents the data retrieved from a query.
Supports methods like next(), getString(), getInt() to navigate and access data.
Handles database access errors and provides information like SQL state, error code, and message.
The typical workflow of a JDBC program involves the following steps:
Load the JDBC Driver
Class.forName("com.mysql.cj.jdbc.Driver");
Establish a Connection
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydb", "username", "password");
Create a Statement
Statement stmt = con.createStatement();
Execute SQL Queries
ResultSet rs = stmt.executeQuery("SELECT * FROM employees");
Process Results
while(rs.next()){
System.out.println(rs.getString("name"));
}
Close Resources
rs.close();
stmt.close();
con.close();
Type 1 – JDBC-ODBC Bridge Driver
Converts JDBC calls into ODBC calls.
Dependent on native libraries; slower and less portable.
Type 2 – Native-API Driver
Uses database-specific native APIs.
Faster than Type 1 but platform-dependent.
Type 3 – Network Protocol Driver
Translates JDBC calls into a database-independent network protocol.
Supports multiple databases via middleware.
Type 4 – Thin or Pure Java Driver
Converts JDBC calls directly into database-specific protocol.
Fully written in Java, portable, and most widely used.
Database Independence: One codebase can work with multiple databases by switching drivers.
Integration with Java: Seamlessly integrates with Java applications and frameworks.
Standard API: Offers uniform interfaces for executing SQL queries and retrieving results.
Supports Advanced Features: Transactions, batch processing, stored procedures, and metadata access.
Security: Supports prepared statements and parameterized queries to prevent SQL injection.
Scalable: Suitable for both small applications and large enterprise-level systems.
Enterprise Applications:
Java EE applications use JDBC to interact with databases for business processes like HR management, finance, and CRM.
Web Applications:
Servlets and JSP applications use JDBC to fetch and display data dynamically from relational databases.
Data Migration:
Moving data between different databases using Java-based migration tools.
Reporting and Analytics:
Applications generate reports from database queries using JDBC to retrieve and process data.
Integration with ORM Tools:
Frameworks like Hibernate internally use JDBC to communicate with relational databases.
Manual Resource Management: Developers must explicitly close connections, statements, and result sets to avoid memory leaks.
Error Handling Complexity: Handling SQL exceptions and database-specific errors can be challenging.
Low-Level API: Requires detailed coding for transaction management, batch processing, and data mapping.
Database-Specific Behavior: SQL dialects may vary between databases, requiring modifications in queries.
Use Prepared Statements: Prevent SQL injection and improve performance.
Close Resources Properly: Always close Connection, Statement, and ResultSet objects in finally blocks or use try-with-resources.
Use Connection Pooling: Use libraries like HikariCP or Apache DBCP for efficient connection management.
Handle Exceptions Gracefully: Log errors and provide meaningful messages.
Optimize Queries: Minimize database calls and avoid unnecessary data retrieval.
Leverage Transactions: Group related SQL operations and use commit and rollback to maintain data integrity.
JDBC (Java Database Connectivity) is a fundamental technology for Java developers to interact with relational databases. It provides a standardized API to connect, query, and manipulate data, making Java applications database-independent and scalable. By supporting transactions, batch processing, stored procedures, and prepared statements, JDBC ensures robust, secure, and efficient database operations.
From enterprise software to web applications and analytics systems, JDBC remains a core component of Java-based data management, bridging the gap between relational databases and modern applications. Understanding JDBC and following best practices enables developers to build reliable, scalable, and maintainable database-driven applications.
Answer:
JDBC (Java Database Connectivity) is an API in Java that allows Java programs to connect and interact with relational databases. It provides methods to query, update, and manage databases using SQL statements.
Answer:
Platform-independent and database-independent
Supports SQL queries execution
Provides transaction management
Supports batch processing
Allows scrollable and updatable result sets
Answer:
| Type | Description | Pros | Cons |
|---|---|---|---|
| Type 1: JDBC-ODBC bridge | Uses ODBC driver | Simple for prototyping | Requires ODBC, not suitable for production |
| Type 2: Native-API | Uses client-side native DB API | Faster than Type 1 | DB-specific, platform-dependent |
| Type 3: Network Protocol | Middleware server converts JDBC to DB protocol | DB-independent | Middleware needed |
| Type 4: Thin driver | Pure Java driver, connects directly to DB | Fast, platform-independent | DB-specific |
| Feature | Statement | PreparedStatement | CallableStatement |
|---|---|---|---|
| Usage | Executes static SQL queries | Executes parameterized queries | Executes stored procedures |
| Performance | Slower | Faster due to pre-compilation | Depends on DB |
| Parameters | No | Yes | Yes |
| SQL Injection | Vulnerable | Safe | Safe |
Answer:
DriverManager: Manages JDBC drivers and establishes connections.
Connection: Represents a connection to a database.
Statement / PreparedStatement / CallableStatement: Executes SQL queries.
ResultSet: Holds the result of SQL queries.
SQLException: Handles database errors.
Answer:
JDBC architecture has two layers:
JDBC API: Interface between Java application and JDBC driver.
JDBC Driver: Translates JDBC calls to database-specific calls.
Flow:
Java Application → JDBC API → JDBC Driver → Database
Answer:
Class.forName("com.mysql.cj.jdbc.Driver"); // Load driver
Connection con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/dbname", "username", "password");
Class.forName loads the driver class
DriverManager.getConnection establishes connection
| Method | Returns | Use Case |
|---|---|---|
| executeQuery() | ResultSet | SELECT queries |
| executeUpdate() | int (rows affected) | INSERT, UPDATE, DELETE |
| execute() | boolean | DDL statements or unknown type |
Answer:
ResultSet is a table of data representing database query results. It supports navigation:
Next() – moves forward
Previous() – moves backward
First(), Last(), Absolute(n), Relative(n) – random access
Answer:
| Type | Description |
|---|---|
| TYPE_FORWARD_ONLY | Can move only forward |
| TYPE_SCROLL_INSENSITIVE | Can scroll, does not reflect DB changes |
| TYPE_SCROLL_SENSITIVE | Can scroll, reflects DB changes |
| Feature | Statement | PreparedStatement |
|---|---|---|
| Precompiled | No | Yes |
| SQL Injection | Vulnerable | Safe |
| Performance | Slower | Faster |
| Parameters | No | Yes |
Answer:
Use try-catch blocks and SQLException methods:
getMessage() – error message
getSQLState() – SQL state code
getErrorCode() – DB-specific error code
try {
// JDBC code
} catch(SQLException e) {
System.out.println(e.getMessage());
System.out.println(e.getSQLState());
System.out.println(e.getErrorCode());
}
Answer:
Batch processing allows executing multiple SQL queries in one go, improving performance:
PreparedStatement ps = con.prepareStatement("INSERT INTO table VALUES(?)");
for(String data : list) {
ps.setString(1, data);
ps.addBatch();
}
ps.executeBatch();
Answer:
By default, auto-commit is true, meaning each SQL statement is committed automatically.
Can be disabled:
con.setAutoCommit(false);
con.commit(); // manual commit
con.rollback(); // rollback on error
| Method | Description |
|---|---|
| commit() | Saves all changes permanently |
| rollback() | Undoes all changes since last commit |
Answer:
CallableStatement cs = con.prepareCall("{call myProcedure(?, ?)}");
cs.setInt(1, 100);
cs.registerOutParameter(2, java.sql.Types.VARCHAR);
cs.execute();
String result = cs.getString(2);
| Feature | JDBC | ODBC |
|---|---|---|
| Language | Java | C |
| Platform | Java apps | Windows/other OS |
| DB Access | Cross-platform | Needs bridge for Java |
Answer:
Connection pooling reuses database connections to improve performance and resource management. Implemented using libraries like Apache DBCP, HikariCP, C3P0.
Answer:
A transaction is a set of SQL statements executed as a single unit. Properties follow ACID principles:
Atomicity, Consistency, Isolation, Durability
Answer:
con.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
Levels:
TRANSACTION_READ_UNCOMMITTED
TRANSACTION_READ_COMMITTED
TRANSACTION_REPEATABLE_READ
TRANSACTION_SERIALIZABLE
| Feature | DriverManager | DataSource |
|---|---|---|
| Connection | Basic connections | Advanced, with pooling |
| Performance | Slower | Faster (supports pooling) |
| Usage | Simple apps | Enterprise apps |
Answer:
java.sql.Driver – interface to implement DB drivers
DriverManager – manages drivers and connections
Connection – connection to DB
Statement/PreparedStatement/CallableStatement – execute queries
ResultSet – hold query results
Answer:
Scrollable: Can move forward, backward, or to a specific row.
Updatable: Can modify data in DB using ResultSet.updateXXX() methods.
Answer:
DatabaseMetaData: Provides DB info like tables, supported SQL features.
DatabaseMetaData dbmd = con.getMetaData();
System.out.println(dbmd.getDatabaseProductName());
ResultSetMetaData: Provides info about query results (column count, type).
Answer:
Use ResultSet.wasNull() after getting value
int age = rs.getInt("age");
if(rs.wasNull()) {
// handle null
}
Answer:
DDL (CREATE, ALTER, DROP) can be executed using Statement.execute():
Statement st = con.createStatement();
st.execute("CREATE TABLE users(id INT, name VARCHAR(20))");
| Type | Behavior |
|---|---|
| TYPE_FORWARD_ONLY | Only forward |
| TYPE_SCROLL_INSENSITIVE | Scrollable, ignores DB changes |
| TYPE_SCROLL_SENSITIVE | Scrollable, reflects DB changes |
Answer:
Batch update executes multiple statements together. Benefits:
Reduced network trips
Improved performance for bulk operations
| Feature | executeQuery() | execute() |
|---|---|---|
| Return | ResultSet | boolean (true if ResultSet returned) |
| Use Case | SELECT | DML, DDL, unknown queries |
Answer:
Use DataSource object, supports connection pooling and is preferred in enterprise applications:
DataSource ds = new MysqlDataSource();
ds.setURL("jdbc:mysql://localhost:3306/db");
Connection con = ds.getConnection();
| Method | Effect |
|---|---|
| Connection.close() | Closes the DB connection |
| Statement.close() | Closes the statement object but not the connection |
Answer:
Prevents SQL injection
Faster execution (precompiled SQL)
Allows dynamic parameters
Answer:
PreparedStatement ps = con.prepareStatement("INSERT INTO users(name) VALUES(?)", Statement.RETURN_GENERATED_KEYS);
ps.setString(1, "John");
ps.executeUpdate();
ResultSet rs = ps.getGeneratedKeys();
if(rs.next()) {
int id = rs.getInt(1);
}
| Feature | executeUpdate() | executeLargeUpdate() |
|---|---|---|
| Return | int (rows affected) | long (rows affected, for large tables) |
Answer:
Use database-independent queries, and load appropriate JDBC driver dynamically. Example: MySQL, Oracle, PostgreSQL.
Answer:
Escape syntax allows database-independent SQL:
{d 'yyyy-mm-dd'} for date
{fn function-name(arguments)} for functions
Answer:
Requires SQL knowledge
Low-level API; verbose code
No native GUI
Less suitable for NoSQL databases
Answer:
CallableStatement cs = con.prepareCall("{? = call myFunction(?)}");
cs.registerOutParameter(1, java.sql.Types.INTEGER);
cs.setInt(2, 100);
cs.execute();
int result = cs.getInt(1);
Answer:
JDBC 4.0 introduced:
Automatic driver loading (no need for Class.forName)
Enhanced exception handling
Support for SQL XML types
Improved RowSet implementations
Answer:
Use Statement.execute() for multiple queries
Navigate using getMoreResults() method
Statement st = con.createStatement();
boolean hasResultSet = st.execute("SELECT * FROM emp; SELECT * FROM dept;");
while(hasResultSet) {
ResultSet rs = st.getResultSet();
// process rs
hasResultSet = st.getMoreResults();
}
Answer:
Always use PreparedStatement or CallableStatement instead of concatenated SQL.
Validate input data before sending it to database.
Q1: What is JDBC?
Answer:
JDBC (Java Database Connectivity) is an API in Java to connect and interact with relational databases.
Supports operations like query execution, data manipulation, and transaction management.
Q2: What are the main components of JDBC?
Answer:
DriverManager / DataSource – Connects Java app to database.
Connection – Represents a session with the database.
Statement / PreparedStatement / CallableStatement – Execute SQL queries.
ResultSet – Retrieve query results.
SQLException – Handle database errors.
Q3: What are the types of JDBC drivers?
Answer:
| Type | Description | Example |
|---|---|---|
| Type 1 | JDBC-ODBC bridge | Sun JDBC-ODBC driver |
| Type 2 | Native API | Oracle OCI driver |
| Type 3 | Network Protocol | Third-party middleware driver |
| Type 4 | Pure Java | MySQL Connector/J, PostgreSQL driver |
Type 4 drivers are preferred due to platform independence and performance.
Q4: Difference between DriverManager and DataSource
Answer:
| Feature | DriverManager | DataSource |
|---|---|---|
| Connection pooling | No | Yes |
| JNDI support | No | Yes |
| Recommended | Simple apps | Enterprise apps |
| Implementation | API-based | Object-based |
Q5: What is the JDBC URL?
Answer:
A URL that specifies database location, driver, and connection parameters.
Format examples:
MySQL: jdbc:mysql://localhost:3306/dbname
Oracle: jdbc:oracle:thin:@localhost:1521:xe
Q6: How do you establish a JDBC connection?
Answer:
Class.forName("com.mysql.cj.jdbc.Driver"); // Load driver
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/dbname", "username", "password");
Q7: Difference between Connection pooling and normal connection
Answer:
Normal connection: Each request creates a new connection → expensive.
Connection pool: Reuses a pool of connections → improves performance.
Libraries: HikariCP, Apache DBCP, C3P0.
Q8: How do you close JDBC resources properly?
Answer:
Always close ResultSet → Statement → Connection in finally block or use try-with-resources:
try (Connection conn = DriverManager.getConnection(url, user, pass);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query)) {
// Process rs
} catch(SQLException e) {
e.printStackTrace();
}
Q9: What is auto-commit in JDBC?
Answer:
Default mode: autoCommit = true.
Each SQL statement is committed immediately.
For transaction control, set conn.setAutoCommit(false) and use commit() or rollback().
Q10: How do you handle transactions in JDBC?
Answer:
conn.setAutoCommit(false);
try {
stmt.executeUpdate(sql1);
stmt.executeUpdate(sql2);
conn.commit();
} catch(SQLException e) {
conn.rollback(); // Undo changes on failure
}
Q11: Difference between Statement, PreparedStatement, and CallableStatement
Answer:
| Feature | Statement | PreparedStatement | CallableStatement |
|---|---|---|---|
| SQL type | Static | Parameterized | Stored procedures |
| Compilation | Each execution | Precompiled | Precompiled |
| Performance | Low | High | High |
| Security | Vulnerable to SQL injection | Safe | Safe |
Q12: How do you prevent SQL injection?
Answer:
Use PreparedStatement with parameters:
PreparedStatement ps = conn.prepareStatement("SELECT * FROM users WHERE id=?");
ps.setInt(1, userId);
ResultSet rs = ps.executeQuery();
Avoid concatenating user input into SQL strings.
Q13: How do you execute a SELECT query?
Answer:
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM employees");
while(rs.next()) {
System.out.println(rs.getInt("id") + " " + rs.getString("name"));
}
Q14: How do you execute INSERT/UPDATE/DELETE?
Answer:
int rows = stmt.executeUpdate("UPDATE employees SET salary=salary+1000 WHERE id=101");
System.out.println(rows + " row(s) updated");
Q15: Difference between execute, executeQuery, executeUpdate
Answer:
| Method | Use case | Return type |
|---|---|---|
| executeQuery | SELECT | ResultSet |
| executeUpdate | INSERT, UPDATE, DELETE | int (rows affected) |
| execute | Any SQL | boolean (true if ResultSet, false if update count) |
Q16: How do you call a stored procedure?
Answer:
CallableStatement cs = conn.prepareCall("{call sp_getEmployee(?, ?)}");
cs.setInt(1, 101); // Input parameter
cs.registerOutParameter(2, Types.VARCHAR); // Output parameter
cs.execute();
String name = cs.getString(2);
Q17: Difference between Statement batching and individual execution
Answer:
Batch execution: Multiple statements executed together → better performance.
stmt.addBatch("INSERT INTO emp VALUES(1,'John')");
stmt.addBatch("INSERT INTO emp VALUES(2,'Jane')");
stmt.executeBatch();
Q18: Types of ResultSet in JDBC
Answer:
| Type | Scrollable | Updatable |
|---|---|---|
| TYPE_FORWARD_ONLY | No | No |
| TYPE_SCROLL_INSENSITIVE | Yes | No |
| TYPE_SCROLL_SENSITIVE | Yes | Yes |
Q19: How do you iterate a ResultSet?
Answer:
while(rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
}
Q20: How do you update ResultSet directly?
Answer:
Use updatable ResultSet:
ResultSet rs = stmt.executeQuery("SELECT * FROM employees", ResultSet.TYPE_SCROLL_SENSITIVE, ResultSet.CONCUR_UPDATABLE);
rs.next();
rs.updateInt("salary", 5000);
rs.updateRow();
Q21: Difference between getString, getInt, getObject
Answer:
| Method | Use case |
|---|---|
| getString | Retrieve as String |
| getInt | Retrieve as integer |
| getObject | Retrieve any type dynamically |
Q22: Difference between absolute, relative, and first/last navigation
Answer:
rs.absolute(n) – Move cursor to nth row.
rs.relative(n) – Move relative to current row.
rs.first(), rs.last() – Move to first/last row.
Q23: What is ResultSetMetaData?
Answer:
Provides information about ResultSet columns: name, type, count.
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
String colName = rsmd.getColumnName(1);
Q24: What is DatabaseMetaData?
Answer:
Provides database-level information: tables, columns, capabilities.
DatabaseMetaData dbmd = conn.getMetaData();
System.out.println(dbmd.getDatabaseProductName());
Q25: Difference between commit and rollback
Answer:
commit() → saves changes permanently.
rollback() → undoes changes since last commit.
Q26: What is isolation level?
Answer:
Controls visibility of uncommitted data.
| Level | Description |
|-------|------------|
| READ_UNCOMMITTED | Dirty reads allowed |
| READ_COMMITTED | No dirty reads |
| REPEATABLE_READ | No dirty or non-repeatable reads |
| SERIALIZABLE | Highest isolation, prevents phantom reads |
conn.setTransactionIsolation(Connection.TRANSACTION_REPEATABLE_READ);
Q27: How do you handle deadlocks?
Answer:
Detect using database tools/logs.
Use consistent order of access, smaller transactions, and retry logic.
Q28: How do you handle concurrent updates?
Answer:
Use optimistic locking: check version/timestamp before update.
Use pessimistic locking: SELECT ... FOR UPDATE.
Q29: Difference between connection.setAutoCommit(true/false)
Answer:
| AutoCommit | Behavior |
|---|---|
| true | Each SQL executes and commits automatically |
| false | Commit manually with conn.commit() |
Q30: How do you handle BLOB and CLOB in JDBC?
Answer:
Blob blob = rs.getBlob("image");
InputStream is = blob.getBinaryStream();
Clob clob = rs.getClob("description");
Reader reader = clob.getCharacterStream();
Q31: How do you handle batch insert for large data?
Answer:
Use PreparedStatement.addBatch() and executeBatch().
Turn off autoCommit for performance.
Q32: What is rowset in JDBC?
Answer:
CachedRowSet / WebRowSet: disconnected, scrollable, serializable result sets.
Can be used offline and reconnected later.
Q33: Difference between Statement caching and PreparedStatement caching
Answer:
Statement caching: Reuses SQL statement object.
PreparedStatement caching: Reuses precompiled SQL → improves performance for repeated queries.
Q34: How do you handle stored procedure with output parameters?
Answer:
CallableStatement cs = conn.prepareCall("{call sp_getName(?, ?)}");
cs.setInt(1, 101);
cs.registerOutParameter(2, Types.VARCHAR);
cs.execute();
String name = cs.getString(2);
Q35: Difference between forward-only and scrollable ResultSet
Answer:
| Type | Features |
|---|---|
| Forward-only | Efficient, read-only, cursor moves forward |
| Scrollable | Navigate freely, can update, slower |
Q36: How do you handle multiple ResultSets from a procedure?
Answer:
boolean hasResultSet = cs.execute();
while (hasResultSet) {
ResultSet rs = cs.getResultSet();
// Process rs
hasResultSet = cs.getMoreResults();
}
Q37: How do you connect to multiple databases in JDBC?
Answer:
Create separate Connection objects for each DB:
Connection conn1 = DriverManager.getConnection(url1, user, pass);
Connection conn2 = DriverManager.getConnection(url2, user, pass);
Or use DataSource pooling for enterprise apps.
Q38: What is JDBC escape syntax?
Answer:
Provides database-independent callable SQL syntax.
Examples:
{d '2026-03-25'} – Date literal
{fn UCASE(column)} – Function escape
Q39: How do you improve JDBC performance?
Answer:
Use PreparedStatement for repeated queries.
Enable batch processing.
Use connection pooling.
Fetch only required columns.
Use indexed columns in WHERE clause.
Q40: How do you debug JDBC issues?
Answer:
Enable driver logging (e.g., MySQL logger).
Use System.out.println for query strings.
Catch SQLException and use getErrorCode() and getSQLState().
Use DB profiling tools for slow queries.
Q41: Difference between JDBC and ODBC
Answer:
| Feature | JDBC | ODBC |
|---|---|---|
| Language | Java | C |
| Platform | Platform-independent | Platform-dependent |
| Type | API | API |
| Performance | Better in Java | Requires native bridge |
Q42: Best practices in JDBC programming
Answer:
Always close ResultSet, Statement, and Connection.
Use PreparedStatement to prevent SQL injection.
Use connection pooling for enterprise apps.
Handle exceptions properly.
Optimize queries for performance.