Unit 5 - Database Connectivity With Java
Unit 5 - Database Connectivity With Java
rd
BE (IT) III Semester
Introduction
JDBC (Java Database Connectivity) is a Java-based API (Application Programming Interface) that provides
a standard method for Java applications to interact with relational databases. It allows Java applications
to establish database connections, send SQL queries to the database, retrieve data from the database,
and update the database records. JDBC is a fundamental technology for building database-driven
applications in Java. Some key features of JDBC are as follows.
1. Database Connectivity: JDBC provides a mechanism to establish a connection to a relational
database management system (RDBMS). It supports a wide range of databases, including
MySQL, Oracle, SQL Server, PostgreSQL, SQLite, and more.
2. Platform Independence: JDBC is designed to be platform-independent. This means that Java
applications written using JDBC can run on different operating systems without modification.
JDBC achieves this by using a driver manager that loads the appropriate database driver
dynamically at runtime.
3. SQL Query Execution: With JDBC, SQL queries can be sent to the database. These queries can
include SELECT statements for data retrieval or INSERT, UPDATE, DELETE statements for data
manipulation.
4. Result Processing: JDBC allows processing the results of SQL queries. The results are typically
returned as result sets, which can be iterated through to access the retrieved data.
Overall, JDBC is a critical technology for developing Java applications that require database connectivity.
It simplifies the process of interacting with databases and provides a standardized way to work with
different database systems. Whether building web applications, desktop applications, or server-side
applications are built, JDBC enables to integrate database functionality seamlessly into Java programs.
JDBC, or Java Database Database Connectivity, is a Java API that is used to interact with databases, issue
queries and commands, and process database result sets. JDBC and database drivers operate together to
access spreadsheets and databases. The API classes and interfaces of JDBC allow an application to send a
request to a particular database. JDBC API helps Java applications interact with ORACLE, MYSQL, and
MSSQL databases.
Java programming language is used for developing enterprise applications. These applications are created
with the purpose of solving real-life problems and need to interact with databases to store required data
and perform operations on it. So, to interact with databases, there is a need for database connectivity,
and for the same purpose, an Open Database Connectivity (ODBC) driver is used.
ODBC is an API by Microsoft and is used to interact with databases. ODBC can only be used by the
Windows platform and can be used for any language such as C, C++, Ruby, Java, etc. On the other hand,
JDBC is an API with interfaces and classes used to interact with databases. It is only used for Java
languages and can be used for any platform. JDBC is highly suggested for Java applications because there
are not any performance or platform dependency problems.
Components of JDBC
Following are the components of JDBC; these elements guide us in interacting with databases.
JDBC API
JDBC Test Suite
JDBC Driver Manager
JDBC-ODBC Bridge Drivers
JDBC API
It is a collection of various methods, classes, and interfaces for smooth communication with a database. It
provides us with two different packages to connect with various databases.
java.sql.*;
javax.sql.*;
Architecture of JDBC
As we can see from the above image, the important components of JDBC are:
Application
These are Java applications such as applets or servlet that communicates with databases
JDBC API
It is an API that is used to create Databases. It uses interfaces and classes to connect with
databases. Some of the essential classes and interfaces defined in JDBC architecture in Java are
the connection Interface and DriverManager class
DriverManager
This is used to create a connection between databases and Java applications. A connection is
established between the Java application and data sources using the getConnection method of
this Class
Data Sources
These are the databases that we can connect with the help of this API. These are the sources
where the data is kept/stored and used by Java applications. JDBC API helps in connecting various
databases such as MYSQL, MSSQL, PostgreSQL, Oracle, etc
JDBC Drivers
These are used to connect with data sources. All databases, such as MSSQL, ORACLE, and MYSQL,
have their drivers. We must load their specific drivers to connect with these databases. Java Class
used for loading driver is Class. Class.forName() method is used to load drivers in JDBC
architecture
Two-Tier Architecture
It is a basic model. In this Model, a Java application and Java applet communicate directly with
the data source
JDBC driver is used to create a connection between the data source and the application.
Whenever an application is required to interact with a database, a query is executed directly on
the data source, and the output of the queries is sent back to the user as a result
This Model is also known as client/server configuration. Here, a user's machine acts as a client
and the machine on which the database is placed acts as a server
Here, the data source can be found on a different machine that is connected to the same
network as the user.
Three-Tier Architecture
This Model is a more secure and complex model of JDBC architecture in Java
The user queries are sent to the middleware tier and then executed on the data source
In this Model, the Java application is treated as one tier connected to the 3rd tier, i.e., data
source using middle-tier services
The results received on the database are again sent to the middle tier and then to the
application/user
import java.sql.*;
import java.sql.*;
try {
// Load the Native-API driver
Class.forName("com.vendor.NativeAPIDriver");
import java.sql.*;
import java.sql.*;
It should be noted that the specific driver class and connection URL depend on the database vendor.
In the examples shown above, placeholders like your_odbc_datasource, com.vendor.NativeAPIDriver,
jdbc:dbmiddleware:your_database, and jdbc:oracle:thin:@your_database_host:1521:your_sid are
subjected to be replaced with actual values according to the database and driver configurations. Also,
handle exceptions appropriately in a production environment.
The choice of JDBC driver type depends on factors such as performance, platform requirements, and
database support. In modern applications, Type 4 drivers (Thin Drivers) are commonly used due to their
platform independence and better performance compared to Type 1 and Type 2 drivers. The selection of
the appropriate driver type is crucial for efficient and reliable database connectivity in Java applications.
import java.sql.Connection;
import java.sql.DriverManager;
Connection connection =
DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb",
"username", "password");
ResultSet
1. Creating a ResultSet
A ResultSet is typically obtained by executing a query on a Statement. A basic example is as follows.
}
} catch (SQLException e) {
e.printStackTrace();
}
2. Handling SQLException
We use try-catch blocks to handle SQLException. Common practices include logging the exception, rolling
back transactions, and closing resources.
while (resultSet.next()) {
// Process the ResultSet
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println("ID: " + id + ", Name: " + name);
}
} catch (SQLException e) {
e.printStackTrace();
// Handle the exception: log, display an error message, etc.
}
5. SQLWarnings
Additionally, the SQLWarning class is used for warnings generated by the database. It can be retrieved
using the getWarnings() method on the Connection or Statement.
}
}
} catch (SQLException e) {
e.printStackTrace();
// Handle SQLException
}
It's important to handle exceptions appropriately in JDBC code to ensure robustness and reliability when
interacting with databases. Proper exception handling helps in diagnosing and resolving issues during
development, testing, and production use.
try {
// Create a connection to the database
Connection connection =
DriverManager.getConnection(jdbcUrl);
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
try {
// Create a connection to the database
Connection connection =
DriverManager.getConnection(jdbcUrl);
preparedStatement.close();
connection.close();
if (rowsAffected > 0) {
System.out.println("Record inserted successfully.");
} else {
System.out.println("Record insertion failed.");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
In this example, we
Define the JDBC URL for connecting to the SQLite database (jdbc:sqlite:mydatabase.db). It can
be replaced with the appropriate URL for desired database system.
Establish a connection to the database using DriverManager.getConnection().
Define an SQL statement (insertSQL) to insert a record into the "users" table with placeholders
for the values.
Create a PreparedStatement to safely insert data with placeholders.
Set values for the placeholders using setString().
Execute the PreparedStatement using executeUpdate() to insert the record.
Close the PreparedStatement and connection.
Check the number of rows affected by the insertion and print a success or failure message.
It has to make sure to replace the values and column names with the actual data we want to insert into
desired database. Additionally, handle exceptions and resource management as needed in a production
environment.
assume that we are working with a SQLite database, but we can adapt it for other databases with the
appropriate JDBC driver.
Step 1: Set up the project
Firstly, it should be ensured that the JDBC driver for the desired database included in the
project's classpath. For SQLite, we can download the SQLite JDBC driver (e.g., sqlite-jdbc-
3.34.0.jar) from the SQLite JDBC website or use a build tool like Maven or Gradle to manage the
dependencies.
Step 2: Write the Java program
In the following Java program, we can see that it connects to a SQLite database, retrieves data
from a table, and prints it.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
try {
// Create a connection to the database
Connection connection =
DriverManager.getConnection(jdbcUrl);
PreparedStatement preparedStatement =
connection.prepareStatement(sqlQuery);
In this example,
jdbcUrl specifies the JDBC URL for the database. We replace it with the appropriate URL for the
desired database system.
We establish a connection to the database using DriverManager.getConnection().
The SQL query (sqlQuery) is defined to retrieve data from a hypothetical "users" table. It can be
modified according to the desired database schema.
We create a PreparedStatement to execute the query and retrieve the result set.
We iterate through the result set, extract data, and print it to the console.
Finally, we close the result set, prepared statement, and connection in a finally block to ensure
proper resource management.
It should be make sure that we have the correct JDBC URL, SQL query, and database driver class based
on our specific database system. Additionally, handle exceptions and resource management as needed
in a production environment.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
if (rowsAffected > 0) {
System.out.println("Record updated successfully.");
} else {
System.out.println("No records were updated.");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
In this example, we
Define the JDBC URL for connecting to the SQLite database (jdbc:sqlite:mydatabase.db). it can
be replaced this with the appropriate URL for desired database system.
Establish a connection to the database using DriverManager.getConnection().
Define an SQL statement (updateSQL) to update a record in the "users" table with placeholders
for the values to be updated.
Create a PreparedStatement to safely update data with placeholders.
It has to make sure to replace the values and column names with the actual data we want to update in
the desired database. Additionally, handle exceptions and resource management as needed in a
production environment.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
try {
// Create a connection to the database
Connection connection =
DriverManager.getConnection(jdbcUrl);
if (rowsAffected > 0) {
System.out.println("Record deleted successfully.");
} else {
System.out.println("No records were deleted.");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
In this example, we
Define the JDBC URL for connecting to the SQLite database (jdbc:sqlite:mydatabase.db). it can
be replaced this with the appropriate URL for desired database system.
Establish a connection to the database using DriverManager.getConnection().
Define an SQL statement (deleteSQL) to delete a record from the "users" table with a
placeholder for the value to be deleted.
Create a PreparedStatement to safely delete data with a placeholder.
It has to make sure to replace the values and column names with the actual data we want to delete in
our database. Additionally, handle exceptions and resource management as needed in a production
environment.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
preparedStatement.setString(2, inputPassword);
} catch (SQLException e) {
e.printStackTrace();
}
}
}
In this example, the input values are set using setString() on the PreparedStatement, and they replace the
placeholders (?). This ensures that user input is treated as data and not executable SQL code.
By using Prepared Statements, you significantly reduce the risk of SQL injection, as the database treats
user input as data rather than executable code. Always validate and sanitize user input, and avoid building
SQL queries by concatenating strings with user input.
1. Types of RowSets
There are several types of RowSets, including JdbcRowSet, CachedRowSet, WebRowSet, JoinRowSet, and
FilteredRowSet. Each has its specific use cases.
2. Disconnected Operation
One of the advantages of RowSets is that they can operate in a disconnected mode. This means that after
retrieving data from the database, the connection can be closed, and the RowSet can continue to work
with the data locally.
3. Ease of Use
RowSets provide a simpler and more intuitive API compared to traditional ResultSet, making it easier to
work with database rows.
For example,
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import javax.sql.rowset.CachedRowSet;
import javax.sql.rowset.RowSetFactory;
import javax.sql.rowset.RowSetProvider;
try {
// Create a RowSetFactory
RowSetFactory rowSetFactory = RowSetProvider.newFactory();
// Create a CachedRowSet
} catch (SQLException e) {
e.printStackTrace();
}
}
}
Transactions in Java
Transactions in Java, specifically in the context of JDBC, are used to group multiple database operations
into a single atomic unit. A transaction ensures that either all the operations within the unit are
completed successfully (commit), or none of them are executed (rollback) in case of an error.
1. Transaction Management
Transactions are managed through the Connection object in JDBC. The commit() method is used to apply
changes, and the rollback() method is used to discard changes.
2. Auto-commit Mode
By default, a Connection is in auto-commit mode, where each SQL statement is treated as a separate
transaction. You can disable auto-commit mode using the setAutoCommit(false) method.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
try {
// Perform multiple SQL operations
} catch (SQLException e) {
// Rollback the transaction in case of an error
connection.rollback();
System.out.println("Transaction rolled back due to an
error.");
e.printStackTrace();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
In this example, the setAutoCommit(false) method is used to disable auto-commit mode. The operations
are grouped within a transaction, and the commit() method is called if all operations succeed. If an error
occurs, the rollback() method is called to discard the changes. This ensures the atomicity of the
transaction.
SQL Escapes
SQL escapes in Java refer to the process of properly handling special characters or reserved keywords in
SQL queries to avoid SQL injection vulnerabilities. SQL injection occurs when untrusted input is directly
concatenated into SQL queries, allowing attackers to manipulate the queries and potentially gain
unauthorized access or manipulate data.
In Java, the PreparedStatement class is commonly used to execute SQL queries with proper handling of
escapes. PreparedStatement supports parameterized queries, allowing you to set parameters without
directly concatenating user input into the SQL query string. An example of using PreparedStatement to
prevent SQL injection is as follows.
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
} catch (SQLException e) {
e.printStackTrace();
}
}
}
In this example, the PreparedStatement is used with a parameterized query ("SELECT * FROM users
WHERE username = ?"). The user input is set as a parameter using the setString(1, userInput) method,
which ensures that the input is properly escaped and prevents SQL injection.
The following points have to be brought into considerations.
Use PreparedStatement to handle parameterized queries.
Set parameters using specific setter methods (setString, setInt, etc.) to ensure proper escaping.
Avoid concatenating user input directly into SQL queries.
By following these practices, the risk of SQL injection vulnerabilities in a Java application is reduced.