Introduction to JDBC
Introduction to JDBC Interview with follow-up questions
1. What is JDBC and why is it used?
JDBC (Java Database Connectivity) is the standard Java API for talking to relational databases. It provides a vendor-neutral set of interfaces (Connection, Statement/PreparedStatement, ResultSet) so your code is written once and works against MySQL, PostgreSQL, Oracle, etc. — each vendor ships a JDBC driver that implements the API.
What you do with it: open a connection, execute SQL (queries and updates), read results from a ResultSet, and manage transactions.
String sql = "SELECT name FROM users WHERE id = ?";
try (Connection con = dataSource.getConnection();
PreparedStatement ps = con.prepareStatement(sql)) {
ps.setLong(1, id);
try (ResultSet rs = ps.executeQuery()) {
if (rs.next()) return rs.getString("name");
}
}
The 2026 framing interviewers want: JDBC is the low-level foundation, but you rarely write raw JDBC in application code today. Most projects use a layer on top — an ORM/JPA (Hibernate) or a lightweight mapper (Spring JdbcClient/JdbcTemplate, jOOQ, MyBatis) — which still run on JDBC underneath. Also note the driver auto-loads via the service-provider mechanism since JDBC 4 (no Class.forName needed), you should always use PreparedStatement (prevents SQL injection), try-with-resources to close connections/statements, and a connection pool (HikariCP) in production rather than opening connections per request.
Follow-up 1
Can you explain the architecture of JDBC?
The architecture of JDBC consists of the following components:
JDBC API: It provides the classes and interfaces for connecting to a database, executing SQL queries, and processing the results.
JDBC Driver Manager: It manages the available JDBC drivers and provides methods to establish a connection to a database.
JDBC Driver: It is a software component that translates the JDBC API calls into the database-specific protocol. There are four types of JDBC drivers: Type 1 (JDBC-ODBC bridge), Type 2 (Native API partly Java driver), Type 3 (Network Protocol pure Java driver), and Type 4 (Thin pure Java driver).
Database: It is the actual database system where the data is stored.
Follow-up 2
What are the steps involved in establishing a JDBC connection?
The steps involved in establishing a JDBC connection are as follows:
Load the JDBC driver class using
Class.forName()method.Create a connection URL string that specifies the database to connect to.
Create a connection object using the
DriverManager.getConnection()method, passing the connection URL, username, and password.Use the connection object to execute SQL queries and perform database operations.
Close the connection using the
connection.close()method to release the resources.
Follow-up 3
What are the different types of JDBC drivers available?
There are four types of JDBC drivers available:
Type 1 (JDBC-ODBC bridge): It uses the ODBC (Open Database Connectivity) API to connect to the database. It requires the ODBC driver to be installed on the client machine.
Type 2 (Native API partly Java driver): It uses the database-specific API provided by the database vendor. It requires the database-specific client library to be installed on the client machine.
Type 3 (Network Protocol pure Java driver): It uses a middleware server to communicate with the database. It requires the middleware server to be installed and configured.
Type 4 (Thin pure Java driver): It is a pure Java driver that communicates directly with the database using the database-specific protocol. It does not require any additional software to be installed.
Follow-up 4
How does JDBC handle SQL exceptions?
JDBC handles SQL exceptions using the try-catch block. When executing SQL queries or database operations, if an exception occurs, it is thrown as an instance of the SQLException class. To handle the exception, you can use a try-catch block and catch the SQLException.
Here is an example:
try {
// JDBC code to execute SQL queries or perform database operations
} catch (SQLException e) {
// Handle the exception
e.printStackTrace();
}
2. What is the role of DriverManager in JDBC?
DriverManager is the JDBC class that manages registered drivers and hands out connections. You give it a JDBC URL (plus credentials), and it selects the matching registered driver and returns a Connection:
Connection con = DriverManager.getConnection(
"jdbc:postgresql://localhost:5432/app", "user", "pass");
The crucial 2026 update interviewers want: since JDBC 4.0 (Java 6), drivers are auto-registered via the Service Provider Interface (META-INF/services), so the old Class.forName("com.mysql.cj.jdbc.Driver") call is no longer needed — just having the driver JAR on the classpath is enough. Citing Class.forName as a required step is outdated.
The bigger point: in real applications you rarely use DriverManager directly — you use a DataSource backed by a connection pool (HikariCP, the Spring Boot default). DriverManager opens a brand-new physical connection each time (expensive); a pooled DataSource reuses connections, which is essential for performance and scalability. So a strong answer is: "DriverManager resolves a driver from the URL and creates connections, but production code uses a pooled DataSource instead, and drivers auto-register since JDBC 4."
Follow-up 1
How does DriverManager decide which driver to load?
The DriverManager uses the JDBC URL provided to determine which driver to load. The JDBC URL typically contains information about the database type, hostname, port, and other connection parameters. Based on this information, the DriverManager searches for a suitable driver that can handle the specified database type. The driver class must be registered with the DriverManager before it can be loaded.
Follow-up 2
What is the purpose of the registerDriver method in DriverManager?
The registerDriver method in DriverManager is used to register a JDBC driver with the DriverManager. This method is typically called by the driver itself during its initialization process. By registering the driver, the DriverManager becomes aware of its existence and can load it when required. The registerDriver method takes an instance of the driver class as a parameter.
Follow-up 3
Can you explain the concept of driver loading in JDBC?
In JDBC, driver loading refers to the process of loading the appropriate driver class based on the JDBC URL provided. The driver class is responsible for establishing a connection to the database and executing SQL statements. The driver loading process is handled by the DriverManager class. When a connection is requested, the DriverManager searches for a suitable driver based on the JDBC URL and loads the corresponding driver class. Once the driver class is loaded, an instance of the driver class is created and used to establish the connection.
3. What is a PreparedStatement in JDBC and how is it different from Statement?
A PreparedStatement is a precompiled, parameterized SQL statement. It extends Statement, using ? placeholders for values that you bind with typed setters (setString, setInt, …). The DB can parse/plan the SQL once and reuse it with different parameter values.
String sql = "SELECT * FROM users WHERE email = ? AND active = ?";
try (PreparedStatement ps = con.prepareStatement(sql)) {
ps.setString(1, email);
ps.setBoolean(2, true);
ResultSet rs = ps.executeQuery();
}
How it differs from Statement, and why it's strongly preferred:
- Security — prevents SQL injection. Parameters are sent separately from the SQL, so user input can never alter the query structure. With
Statementyou concatenate strings, which is the classic injection vulnerability. This is the #1 reason to use PreparedStatement. - Performance. The statement is precompiled (and often cached by the driver/DB), so re-executing it with new values skips re-parsing — a clear win in loops/batches.
- Correct type handling. Setters handle escaping, dates, nulls, and types properly (no manual quoting).
- Cleaner code and support for batch execution (
addBatch/executeBatch).
The framing interviewers reward: always use PreparedStatement for any query involving variables — Statement is only acceptable for fixed, parameter-free SQL. Security first, performance second.
Follow-up 1
Why is PreparedStatement preferred over Statement?
PreparedStatement is preferred over Statement for several reasons:
Performance: PreparedStatement is precompiled and cached by the database server, which improves performance when executing the same SQL statement multiple times with different parameter values.
Security: PreparedStatement helps prevent SQL injection attacks by automatically escaping special characters in the parameter values.
Readability and maintainability: PreparedStatement allows you to write parameterized SQL statements, which makes the code more readable and easier to maintain.
Follow-up 2
Can you explain how to use PreparedStatement to execute a query?
To use PreparedStatement to execute a query, you need to follow these steps:
Create a Connection object to establish a connection to the database.
Prepare the SQL statement by creating a PreparedStatement object using the Connection.prepareStatement() method. Pass the SQL statement as a parameter to the method.
Set the parameter values using the setXXX() methods of the PreparedStatement object, where XXX is the data type of the parameter.
Execute the query using the executeQuery() method of the PreparedStatement object.
Process the ResultSet returned by the executeQuery() method to retrieve the query results.
Close the ResultSet, PreparedStatement, and Connection objects to release the resources.
Follow-up 3
What are the advantages of using PreparedStatement in terms of performance?
Using PreparedStatement can provide the following performance advantages:
Query plan caching: PreparedStatement is precompiled and cached by the database server, which means that the database server can reuse the query plan for subsequent executions of the same SQL statement. This eliminates the need for the database server to recompile the SQL statement each time it is executed, resulting in improved performance.
Reduced network traffic: PreparedStatement allows you to use parameter placeholders in the SQL statement. This means that you can reuse the same SQL statement with different parameter values, reducing the amount of data that needs to be sent over the network.
Improved database optimization: By using PreparedStatement, the database server can optimize the execution plan for the SQL statement based on the parameter values. This can result in better query performance compared to using a Statement where the SQL statement is compiled and executed each time it is called.
4. What is ResultSet in JDBC?
A ResultSet is the object that holds the rows returned by a query (executeQuery). It acts as a cursor: initially positioned before the first row, you call next() to advance, then read columns by name or index with typed getters:
try (ResultSet rs = ps.executeQuery()) {
while (rs.next()) {
long id = rs.getLong("id");
String name = rs.getString("name");
// map row → object
}
} // rs auto-closed
Points interviewers want:
- Read columns by name (
getString("name")) for clarity, or 1-based index; use the type-appropriate getter (getInt,getTimestamp, etc.), and checkrs.wasNull()for nullable numeric columns. - A
ResultSetis tied to itsStatement/Connection— it's forward-only and read-only by default (you can request scrollable/updatable types, but rarely should). Always close it (try-with-resources) to free DB cursors. - For large results, set a fetch size so the driver streams rows instead of loading everything into memory.
The 2026 framing: raw ResultSet row-by-row mapping is tedious and error-prone, so in practice you let a higher layer do it — Spring's JdbcClient/RowMapper, an ORM (JPA/Hibernate), or a mapper (jOOQ/MyBatis) — all of which consume a ResultSet under the hood and map rows to objects for you. Knowing the cursor model is still essential, but you seldom iterate a ResultSet by hand in modern code.
Follow-up 1
What are the different types of ResultSet in JDBC?
There are three types of ResultSet in JDBC:
TYPE_FORWARD_ONLY: This type of ResultSet allows forward-only traversal of the result set. It does not support scrolling or updating the result set.
TYPE_SCROLL_INSENSITIVE: This type of ResultSet allows both forward and backward traversal of the result set. It is insensitive to changes made to the underlying data source.
TYPE_SCROLL_SENSITIVE: This type of ResultSet allows both forward and backward traversal of the result set. It is sensitive to changes made to the underlying data source.
Follow-up 2
How can you retrieve data from ResultSet?
To retrieve data from a ResultSet, you can use the various get methods provided by the ResultSet interface. These methods allow you to retrieve data of different types, such as getInt, getString, getDouble, etc. You can retrieve data by specifying the column index or the column name.
Follow-up 3
Can you explain the concept of cursor in ResultSet?
In JDBC, a cursor is a pointer that points to a row in a ResultSet. By default, the cursor is positioned before the first row of the ResultSet. You can move the cursor to the next row using the next method. The cursor can also be moved to a specific row using the absolute or relative methods. The cursor allows you to iterate over the rows of the ResultSet and retrieve data from each row.
5. How can you handle transactions in JDBC?
JDBC transactions are controlled on the Connection. By default a connection is in auto-commit mode (each statement commits immediately); to group statements into one atomic unit you disable auto-commit, then explicitly commit or rollback:
try (Connection con = dataSource.getConnection()) {
con.setAutoCommit(false); // begin transaction
try (PreparedStatement debit = con.prepareStatement("UPDATE acct SET bal=bal-? WHERE id=?");
PreparedStatement credit = con.prepareStatement("UPDATE acct SET bal=bal+? WHERE id=?")) {
debit.setBigDecimal(1, amt); debit.setLong(2, from); debit.executeUpdate();
credit.setBigDecimal(1, amt); credit.setLong(2, to); credit.executeUpdate();
con.commit(); // all-or-nothing
} catch (SQLException e) {
con.rollback(); // undo on failure
throw e;
}
} // try-with-resources closes the connection (returns it to the pool)
Points interviewers reward: commit on success, rollback on any exception; use try-with-resources so the connection is always closed/returned to the pool (and reset its auto-commit if the pool reuses it). For finer control, Savepoint allows partial rollback, and setTransactionIsolation(...) controls isolation level (read-committed, repeatable-read, etc.).
The 2026 framing: hand-managing transactions like this is verbose and error-prone, so most apps use declarative transactions — Spring's @Transactional (or JPA/JTA) — which wraps exactly this begin/commit/rollback logic around your method. Knowing the raw JDBC mechanics explains what @Transactional does under the hood, but in real code you'd rarely write it by hand.
Follow-up 1
What is the role of commit and rollback methods in transaction management?
In transaction management, the commit() method is used to permanently save the changes made within a transaction to the database. It marks the end of a successful transaction and makes the changes visible to other users.
On the other hand, the rollback() method is used to undo all the changes made within a transaction and restore the database to its previous state. It is called when an error occurs or when the transaction needs to be canceled.
Both methods are called on the Connection object and are used to control the transaction boundaries.
Follow-up 2
How can you set the auto-commit mode in JDBC?
The auto-commit mode in JDBC determines whether each SQL statement is automatically committed to the database after it is executed. By default, the auto-commit mode is enabled, which means that each statement is committed immediately.
To set the auto-commit mode, you can use the setAutoCommit(boolean autoCommit) method of the Connection object. Pass false as the argument to disable auto-commit mode, and true to enable it.
Here's an example:
Connection connection = DriverManager.getConnection(url, username, password);
connection.setAutoCommit(false); // Disable auto-commit mode
// Perform database operations
// ...
connection.commit(); // Commit the transaction
connection.setAutoCommit(true); // Enable auto-commit mode
connection.close();
Follow-up 3
Can you explain the concept of savepoints in JDBC transactions?
In JDBC transactions, a savepoint is a point within a transaction where you can roll back to if needed. It allows you to divide a transaction into multiple smaller units and selectively roll back to a specific savepoint without rolling back the entire transaction.
To create a savepoint, you can use the setSavepoint() method of the Connection object. This method returns a Savepoint object that represents the savepoint.
Here's an example:
Savepoint savepoint = connection.setSavepoint();
// Perform database operations
// ...
connection.rollback(savepoint); // Roll back to the savepoint
Live mock interview
Mock interview: Introduction to JDBC
- Read your scene and goals
- Talk it out; goals tick off live
- Get a score and stronger lines
Your voice and your AI key never touch our servers; the key stays in this browser and is sent only to Google. Only your round scores are saved to track progress.