JDBC PDF
JDBC PDF
JDBC PDF
VTU
7th sem B.E (CSE/ISE)
JAVA/ J2EE
Notes prepared by
Mr. Ashok Kumar K
9742024066 | [email protected]
www.vtuprojects.com | Final year IEEE project development and training from scratch by Mr. Ashok Kumar K.
Registration started. Contact 9742013378 or 9742024066 and lock your project at the earliest.
INTRODUCTION TO J2EE
1. Standalone applications
Standalone applications are those which works based on “where you write the code is where you run the code”. i.e., if you
want to run a standalone application in a client’s machine, you need to have the code residing in that machine; else the
application is not runnable.
Example: Games (which requires installations), GTalk, etc
2. Web applications
Here it is not required for the code to be present in every client’s machine. Instead, the application will be deployed in a
centralized sever, whereas the clients makes a request to access this application through a web browser. Server processes
multiple clients’ request and makes a response to each client request.
3. Mobile applications
These are the application developed for hand held devices like PDAs, mobile phones, IPODs, IPADs, etc.
J2SE (Java to Standard Edition) is a Java platform designed for standalone applications.
J2EE (Java to Enterprise Edition) is a Java platform designed for Web applications or server side
applications.
J2ME (Java to Micro Edition) is a Java platform designed for Mobile applications.`
J2EE is a multi-tier architecture (four layered architecture). The layers are named as follows:
Client tier
Web tier
Business logic tier
Database tier
Client tier
Any component that is capable of initiating a request to the server is said to sit in the client tier of the J2EE
architecture.
Example for client tier component would be a HTML page, browser, etc
Web tier
Web tier component receives the request from the client tier component and forwards the request to the
appropriate business logic tier to process it. Due to security perspective and other issues, the business logic
is delegated to the next tier.
Example for Web tier component would be a servlet.
The components in this tier are responsible for implementing the core business logic for the request from
client tier.
Example for business logic tier component would be a EJB (Enterprise Java Bean).
It might make a connection to the fourth tier to perform various database operations.
Database tier
The components in this tier are responsible for storing the application’s data.
They provide the application’s data to the upper tiers upon making a request.
Example: MySQL, Oracle, DB2, and Sybase database.
Unit 5:
5.1 Basics
Definition
JDBC (Java Database Connectivity) is an API for the Java programming language that defines how a client may access the database.
It provides methods for querying and updating data in a database. JDBC is oriented towards relational databases.
JDBC classes are present in java.sql package.
History
JDBC was a part of JDK 1.1 (Feb 19, 1997) and was developed by a team named Javasoft of Sun Microsystems.
JDBC Components
JDBC project by Javasoft comprises of two things: JDBC APIs and JDBC Driver
JDBC APIs
JDBC APIs are the library functions that performs common tasks associated with database usage like:
Opening/ Closing the connection with the database, Creating SQL statements, Executing that SQL queries
in the database, and Viewing & Modifying the resulting records
JDBC Driver
A JDBC driver is a software component enabling a Java application to interact with a database. It is the
actual implementation of the defined interfaces in the JDBC API for interacting with your database server.
There are many possible implementations of JDBC drivers. These implementations are categorized as follows:
These drivers implement the JDBC API as a mapping to another data access API, such as ODBC (Open Database
Connectivity). Drivers of this type are generally dependent on a native library, which limits their portability.
Example: The JDBC-ODBC Bridge.
These drivers are written partly in the Java programming language and partly in native code. These drivers use a native
client library specific to the data source to which they connect. Again, because of the native code, their portability is
limited.
Example: Oracle's OCI (Oracle Call Interface) client-side driver.
These drivers use a pure Java client and communicate with a middleware server using a database-independent protocol.
The middleware server then communicates the client's requests to the data source.
These drivers are pure Java and implement the network protocol for a specific data source. The client connects directly to
the data source.
There are five steps in the JDBC process for a Java program to communicate with the database. Let's see them in brief and later
elaborate each step.
Here you should load and initialize the class representing the MySQL JDBC Driver. The code snippet to do
this is given below:
try {
Class.forName("com.mysql.jdbc.Driver");
}
catch (ClassNotFoundException e) {
System.out.println("Couldn't load the Driver");
}
Next, you need to establish a connection with the data source you want to use. A data source can be a
DBMS, a legacy file system, or some other source of data with a corresponding JDBC driver. We use the
static getConnection() method in DriverManager class to get the connection. Its syntax is shown below:
Step 3: Create the SQL Statement and Execute the SQL Query
Statement st = null;
ResultSet rs = null;
String qry = "select * from student";
try {
st = con.createStatement();
rs = st.executeQuery(qry);
} catch (SQLException e) {
System.out.println("Error while processing SQL query");
}
The output of the SQL query will be encapsulated in ResultSet object. A ResultSet object contains zero
or more records (or rows). We should iterate over each record (or row) in order to print it in the console as
demonstrated below:
try {
String id, name;
int age;
double aggregate;
while (rs.next()) {
id = rs.getString("id");
name = rs.getString("name");
age = rs.getInt("age");
aggregate = rs.getDouble("aggr");
System.out.println(id + "\t" + name + "\t" + age +
"\t" + aggregate);
}
} catch (SQLException e) {
System.out.println("Error while processing SQL results");
}
At last, a very important step of all is to close the database connection. This releases the external resources
like cursor, handlers etc. Typically, closing the connection should be done in the finally block.
try {
con.close();
} catch (Exception e) {
System.out.println("Error while closing the connection");
}
Mr. Ashok Kumar K | 9742024066 | [email protected]
www.vtuprojects.com | Final year IEEE project development and training from scratch by Mr. Ashok Kumar K.
Registration started. Contact 9742013378 or 9742024066 and lock your project at the earliest.
When you are using JDBC outside of an application server, the DriverManager class manages the establishment of Connections. You
should specify to the DriverManager which JDBC drivers it should try to make Connections with. The easiest way to do this is to use
Class.forName() on the class that implements the java.sql.Driver interface. With MySQL, the name of this class is
com.mysql.jdbc.Driver.
try {
Class.forName("com.mysql.jdbc.Driver");
}
catch (ClassNotFoundException e) {
System.out.println("Couldn't load the Driver");
}
Make sure that the driver class (com.mysql.jdbc.Driver) is available in the classpath so that it can be loaded and initialized by the
JVM.
Concept
Once the JDBC driver has been loaded and initialized, the Java component can now obtain a connection to the external database
associated with the driver. To do this, you must invoke getConnection() method of DriverManager class passing three arguments
as shown in the syntax below:
Here,
url: a database url of the form jdbc:subprotocol:subname
user: the database user on whose behalf the connection is being made
password: the user's password
Example:
Some databases would require additional details other than username and password to grant the access to the database. The question
here is how would you provide these additional propertied to DriverManager's getConnection() method. This additional information
must be associated with a Properties object which is passed as an argument in getConnection() method.
Example:
Connection con = null;
try {
FileInputStream fis = new FileInputStream( new File("DBProps.txt") );
Properties props = new Properties();
props.load(fis);
con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/college", props);
} catch (SQLException e) {
System.out.println("Couldn't Obtain the connection");
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
Setting Timeout
Whenever a J2EE component requests connection with the external database, there are possibilities where the DBMS may not respond
to it due to various reasons. In this case, the J2EE component will wait indefinitely till the DBMS responds to it. To avoid this indefinite
delay, you can set a timeout period after which the DriverManager will stall (cancel) the attempt to connect to the DBMS.
To set the timeout period, you can use setoginTimeout() method in DriverManager class whose syntax is given below:
Likewise, you can use getLoginTimeout() method to retrieve the current timeout period that has been set. Its syntax is shown below:
A Statement is an interface that represents a SQL statement. You execute Statement objects, and they generate ResultSet objects,
which is a table of data representing a database result set. You need a Connection object to create a Statement object.
For example,
stmt = con.createStatement();
Statement:
Used to implement simple SQL statements with no parameters.
Statement
The Statement object is used whenever a J2EE component needs to immediately execute a query without first having the query
compiled. Before you can use a Statement object to execute a SQL statement, you need to create one using the Connection object's
createStatement() method, as in the following example:
Statement st = null;
try {
st = con.createStatement();
} catch (SQLException e) {
e.printStackTrace();
}
Once you've created a Statement object, you can then use it to execute a SQL statement with one of its three execute methods.
boolean execute(String SQL) : Returns a boolean value of true if a ResultSet object can be retrieved; otherwise, it returns
false. Use this method to execute SQL DDL statements or when you need to use truly dynamic SQL.
int executeUpdate(String SQL) : Returns the numbers of rows affected by the execution of the SQL statement. Use this
method to execute SQL statements for which you expect to get a number of rows affected - for example, an INSERT,
UPDATE, or DELETE statement.
ResultSet executeQuery(String SQL) : Returns a ResultSet object. Use this method when you expect to get a result set,
as you would with a SELECT statement.
Just as you close a Connection object to save database resources, for the same reason you should also close the Statement object. A
simple call to the close() method will do the job.
Example:
import java.sql.*;
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/college",
"root", "lordshiva");
String qry = "select * from student";
st = con.createStatement();
rs = st.executeQuery(qry);
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
st.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output:
PreparedStatement
The PreparedStatement is used to compile the query first before executing it. The PreparedStatement interface extends the
Statement interface which gives you added functionality. This statement gives you the flexibility of supplying input arguments
dynamically. All parameters (arguments) are represented by the ? symbol, which is known as the place holder. You must supply values
for every parameter before executing the SQL statement. The setXXX() methods bind values to the parameters, where XXX
represents the Java data type of the value you wish to bind to the input parameter. Each parameter marker is referred to by its ordinal
position. The first marker represents position 1, the next position 2, and so forth. If you forget to supply the values, you will receive an
SQLException. All of the Statement object's methods for interacting with the database: execute(), executeQuery(), and
executeUpdate() also work with the PreparedStatement object. However, the methods are modified to use SQL statements that can
take input the parameters..
Example
PreparedStatement ps = null;
try {
String qry = "update student set name=? where id=?";
ps = con.prepareStatement(qry);
ps.setString(1, "Ashok Kumar");
ps.setString(2, "1VK06IS009");
ps.execute();
}
catch (SQLException e) {
Just as you close a Statement object, for the same reason you should also close the PreparedStatement object. A simple call to the
close() method will do the job.
CallableStatement
CallableStatement object is used to execute a call to the stored procedure from within a J2EE object. The stored procedure can be
written in PL/SQL, Transact-SQL, C, or another programming language. The stored procedure is a block of code and is identified by a
unique name.
Here is the simple MySQL stored procedure:
IN: A parameter whose value is unknown when the SQL statement is created. You bind values to IN parameters with the
setXXX() methods.
OUT: A parameter whose value is supplied by the SQL statement it returns. You should register this parameter using
registerOutParameter() method. You retrieve values from the OUT parameters with the getXXX() methods.
INOUT: A parameter that provides both input and output values. You bind variables with the setXXX() methods and retrieve
values with the getXXX() methods.
Example
CallableStatement cs = null;
try {
String qry = "{CALL getStudName (?,?) }";
cs = con.prepareCall(qry);
cs.setString(1, "1VK06IS009");
cs.registerOutParameter(2, Types.VARCHAR);
cs.execute();
Just as you close other Statement object, for the same reason you should also close the CallableStatement object. A simple call to
the close() method will do the job.
String qry = "select * from student"; String qry = "update student String qry = "{CALL
set name=? where id=?"; getStudName (?,?) }";
Statement st = con.createStatement();
PreparedStatement ps = CallableStatement cs =
rs = st.executeQuery(qry); con.prepareStatement(qry); con.prepareCall(qry);
ps.execute(); cs.execute();
As you know, the executeQuery() method is used to send the query to the DBMS and returns a ResultSet object that contains data
that was requested by the query. A ResultSet object maintains a virtual cursor that points to a row in the result set. The term "result
set" refers to the virtual table of row and column data contained in a ResultSet object. The virtual cursor is initially positioned above
the first row of data when the ResultSet is returned by executeQuery() method.
There are various methods in the ResultSet interface. These methods can be grouped into three categories as follows
Get methods: used to view the data in the columns of the current row being pointed by the virtual cursor.
Navigational methods: used to move the virtual cursor around the virtual table.
Update methods: used to update the data in the columns of the current row.
There is a get method in ResultSet interface for each of the possible data types of the form getXXX() where XXX is the data type of
the column, and each get method has two versions:
One that takes in a column name
Example:
String name = rs.getString("name");
One that takes in a column index.
Example:
String name = rs.getString(1);
Example:
import java.sql.*;
Output:
Types of ResultSet
You should specify one of the type of ResultSet while creating a Statement object. You should pass this as an argument to
createStatement() or preparedStatement() method. If you don't specify anything, the default one will be TYPE_FORWARD_ONLY.
Concurrency of ResultSet
Rows contained in ResultSet's virtual table can either be read only or be updatable. This selection can be made by passing either one
of the below as an argument to createStatement() or preparedStatement() method.
Example 1:
Statement st = null;
st=con.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,ResultSet.CONCUR_UPDATABLE);
Example 2:
Statement st = null;
st=con.createStatement(ResultSet.TYPE_SCROLL_SENSITIVE,ResultSet.CONCUR_UPDATABLE);
Scrolling a ResultSet
There are several methods in the ResultSet interface that involve moving the cursor. They are:
1
Moves the cursor to the front of this ResultSet object, just before the first row. This method has no effect if the result set
contains no rows.
2
Moves the cursor to the end of this ResultSet object, just after the last row. This method has no effect if the result set
contains no rows.
Moves the cursor to the given row number in this ResultSet object.
If the row number is positive, the cursor moves to the given row number with respect to the beginning of the result set.
The first row is row 1, the second is row 2, and so on.
5
If the given row number is negative, the cursor moves to an absolute row position with respect to the end of the result
set. For example, calling the method absolute(-1) positions the cursor on the last row; calling the method absolute(-2)
moves the cursor to the next-to-last row, and so on.
An attempt to position the cursor beyond the first/last row in the result set leaves the cursor before the first row or after
the last row.
6 Moves the cursor a relative number of rows, either positive or negative. Attempting to move beyond the first/last row in
the result set positions the cursor before/after the first/last row. Calling relative(0) is valid, but does not change the
cursor position.
Moves the cursor froward one row from its current position. A ResultSet cursor is initially positioned before the first row;
the first call to the method next makes the first row the current row; the second call makes the second row the current
8
row, and so on.
When a call to the next method returns false, the cursor is positioned after the last row. Any invocation of a ResultSet
method which requires a current row will result in a SQLException being thrown.
10 Moves the cursor to the insert row. The current cursor position is remembered while the cursor is positioned on the
insert row. The insert row is a special row associated with an updatable result set. It is essentially a buffer where a new
row may be constructed by calling the updater methods prior to inserting the row into the result set
11 Moves the cursor to the remembered cursor position, usually the current row. This method has no effect if the cursor is
not on the insert row.
Note 1: Not all the Drivers are scrollable. Here is the code snippet to test whether a driver supports a
scrollable ResultSet
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = null;
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/college",
"root", "lordshiva");
} catch (Exception e) {
e.printStackTrace();
}
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = null;
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/college",
"root", "lordshiva");
Statement st = con.createStatement();
st.setFetchSize(200);
ResultSet rs = st.executeQuery("select * from student");
} catch (Exception e) {
e.printStackTrace();
}
Updating a ResultSet
The ResultSet interface contains a collection of update methods for updating the data of a result set. As with the get methods, there
are two updateXXX() methods for each data type, where XXX is the data type of the column:\
Updating a row in the result set changes the columns of the current row in the ResultSet object (virtual table), but not in the underlying
database. To update your changes to the row in the database, you need to invoke one of the following methods.
Examples:
rs = st.executeQuery(qry);
while (rs.next()) {
if (rs.getString("name").equals("Ashok")) {
rs.updateString("name", "Ashok Kumar");
rs.updateRow();
}
}
2. Deleting a Row
rs = st.executeQuery(qry);
while (rs.next()) {
if (rs.getString("name").equals("Prasad")) {
rs.deleteRow();
}
}
A Database Transaction consists of a set of SQL statements, each of which must be successfully completed for the transaction to be
completed. If one fails, SQL statements that executed successfully up to that point in the transaction must be rolled back.
A database transaction, by definition, must be atomic, consistent, isolated and durable. Database practitioners often refer to these
properties of database transactions using the acronym ACID.
Atomicity:
Atomicity requires that each transaction is "all or nothing": if one part of the transaction fails, the entire transaction fails, and
the database state is left unchanged. An atomic system must guarantee atomicity in each and every situation, including power
failures, errors, and crashes. To the outside world, a committed transaction appears (by its effects on the database) to be
indivisible ("atomic"), and an aborted transaction does not happen.
Consistency:
The consistency property ensures that any transaction will bring the database from one valid state to another. Any data written
to the database must be valid according to all defined rules, including but not limited to constraints, cascades, triggers, and
any combination thereof.
A Transactional database is a DBMS where write transactions on the database are able to be rolled back if they are not completed
properly (e.g. due to power or connectivity loss). Most modern relational database management systems fall into the category of
databases that support transactions.
A database transaction isn't completed until the J2EE component calls the commit() method of the Connection object. All SQL
statements executed prior to the call to the commit() method can be rolled back. However, once the commit() method is called, none of
the SQL statements can be rolled back.
The commit() method must be called regardless if the SQL statement is part of a transaction or not. Till now, we never issued a
commit() on the database but still we were able to save the data in the database. This is because of the auto commit feature of the
database connection.
If a J2EE component is implementing a transaction, then the auto commit feature should be turned off. This can be done as follows:
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = null;
con = DriverManager.getConnection("jdbc:mysql://localhost:3306/college",
"root", "lordshiva");
con.setAutoCommit(false);
} catch (Exception e) {
e.printStackTrace();
}
Let's see a simple transaction processing example. Below program executes two SQL queries, both of which update the student's
aggregate and age. Each SQL statement will be executed separately and a commit() method is called upon success. However, if any of
the statement fails (throws an exception), the transaction is rolled back by invoking rollback() method in the catch clause.
import java.sql.*;
try {
Class.forName("com.mysql.jdbc.Driver");
st1 = con.createStatement();
st2 = con.createStatement();
st1.execute(qry1);
st2.execute(qry2);
con.commit();
} catch (Exception e) {
System.out.println("Transaction failed ..");
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
finally {
try {
st1.close();
st2.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Using savepoints
A transaction may consist of many tasks, some of which don't need to be rolled back when the transaction fails. The J2EE component
can control the number of tasks that are rolled back by using savepoints. A savepoint is a virtual marker that defines the task at which
the rollback stops.
When you set a savepoint you define a logical rollback point within a transaction. If an error occurs past a savepoint, you can use the
rollback method to undo either all the changes or only the changes made after the savepoint.
Example,
Here we execute two SQL statements. After executing one SQL statement, a savepoint is set. The transaction is rolled back till this
savepoint after executing both the statements. Thus only second SQL statement will be rolled back and the first SQL statement will be
committed.
import java.sql.*;
try {
Class.forName("com.mysql.jdbc.Driver");
Mr. Ashok Kumar K | 9742024066 | [email protected]
www.vtuprojects.com | Final year IEEE project development and training from scratch by Mr. Ashok Kumar K.
Registration started. Contact 9742013378 or 9742024066 and lock your project at the earliest.
con = DriverManager.getConnection
"jdbc:mysql://localhost:3306/college", "root", "lordshiva");
con.setAutoCommit(false);
st1 = con.createStatement();
st2 = con.createStatement();
st1.execute(qry1);
st2.execute(qry2);
con.rollback(sp1);
con.releaseSavepoint(sp1);
con.commit();
} catch (Exception e) {
System.out.println("Transaction failed ..");
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
finally {
try {
st1.close();
st2.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Batch Processing allows you to group related SQL statements into a batch and submit them with one call to the database. When you
send several SQL statements to the database at once, you reduce the amount of communication overhead, thereby improving
performance.
The addBatch() method of Statement, PreparedStatement, and CallableStatement is used to add individual statements to the
batch. The executeBatch() is used to start the execution of all the statements grouped together.
The executeBatch() returns an array of integers, and each element of the array represents the update count for the respective update
statement. A value of -1 indicates the failure of update statement.
Mr. Ashok Kumar K | 9742024066 | [email protected]
www.vtuprojects.com | Final year IEEE project development and training from scratch by Mr. Ashok Kumar K.
Registration started. Contact 9742013378 or 9742024066 and lock your project at the earliest.
Just as you can add statements to a batch for processing, you can remove them with the clearBatch() method. This method removes
all the statements you added with the addBatch() method. However, you cannot selectively choose which statement to remove
Example
import java.sql.*;
try {
Class.forName("com.mysql.jdbc.Driver");
st1 = con.createStatement();
st1.addBatch(qry1);
st1.addBatch(qry2);
st1.addBatch(qry3);
st1.executeBatch();
st1.clearBatch();
con.commit();
} catch (Exception e) {
System.out.println("Transaction failed ..");
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
e.printStackTrace();
}
finally {
try {
st1.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
There are two types of metadata that can be retrieved from the DBMS.
DatabaseMetaData which is the data about the database
ResultSetMetaData which is the data about the Result Set
DatabaseMetaData
Meta data is the data about the data. A J2EE component can access the metadata by using the DatabaseMetaData interface. It is used
to retrieve information about databases, tables, column, indexes, etc.
getMetaData() method of Connection object is used to retrieve the metadata about the database. Here are some of the methods
available in DatabaseMetaData interface:
Example
import java.sql.*;
try {
Class.forName("com.mysql.jdbc.Driver");
con = DriverManager.getConnection
("jdbc:mysql://localhost:3306/college", "root", "lordshiva");
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
Output:
ResultSetMetaData
ResultSetMetaData interface describes the Result set (virtual database). getMetaData() method of the ResultSet object can be used
to retrieve the Result set metadata. The most commonly used methods in ResultSetMetaData interface are:
Example
import java.sql.*;
} catch (Exception e) {
e.printStackTrace();
}
finally {
try {
st.close();
con.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
Output:
5.10 Exceptions
There are three kinds of exceptions that are thrown by JDBC methods.
SQLException:
It commonly reflects a syntax error in the query and is thrown by many of the methods contained in java.sql package.
SQLWarning:
It throws warnings received by the connection from the DBMS. The getWarning() method of the Connection object retrieves
the warning and the getNextWarning() method retrieves the subsequent warnings.
DataTruncation:
It is thrown whenever a data is lost due to the truncation of the data value.