Unit 1 JDBC
Unit 1 JDBC
Unit 1 JDBC
JDBC stands for Java DataBase Connectivity, which is a standard java API for database independent
connectivity between the java programming language and a wide range of databases, via the Structured Query
Language (SQL). JDBC is a key enterprise API.
JDBC library includes API for each of the tasks mentioned below that are commonly associated with database
usage.
This is for making the JDBC API classes immediately available to the application program. The
following import statement should be included in the program irrespective of the JDBC driver being used:
import java.sql.*;
2)Load and register the JDBC driver
The forName() method of Class class is used to register the driver class. This method is used to
dynamically load the driver class.
For ms access driver
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
For mysql
Class.forName("com.mysql.jdbc.Driver");
3)Create the connection object
The getConnection() method of DriverManager class is used to establish connection with the database.
Connection con=DriverManager.getConnection( "url","username","password");
For ms access
Connection con = DriverManager.getConnection("jdbc:odbc:companydb","", "");
For mysql
Connectioncon=DriverManager.getConnection("jdbc:mysql://localhost://companydb","root","password");
4)Create the Statement object
The createStatement() method of Connection interface is used to create statement. The object of
statement is responsible to execute queries with the database.
Statement stmt = con.createStatement();
5)Execute the query
The executeQuery() method of Statement interface is used to execute queries to the database. This method
returns the object of ResultSet that can be used to get all the records of a table.
while(rs.next())
{
System.out.println(rs.getString(1));
}
rs.close(); stmt.close(); con.close();
}
}
statements In JDBC
Once you have created a Connection, you can begin using it to execute SQL statements. This is usually
done via Statement objects.
There are actually three kinds of statements in JDBC:
Statement
Represents a basic SQL statement
PreparedStatement
Represents a precompiled SQL statement, which can offer improved performance
CallableStatement
Allows JDBC programs complete access to stored procedures within the database itself
1)Statement
Once you have created a Statement, you use it to execute SQL statements. A statement can either be a
query that returns results or an operation that manipulates the database in some way. If you are performing
a query, use the executeQuery() method of the Statement object:
ResultSet rs = stmt.executeQuery("SELECT * FROM CUSTOMERS");
Here we've used executeQuery() to run a SELECT statement. This call returns a ResultSet object that
contains the results of the query (we'll take a closer look at ResultSet in the next section). Statement also
provides an executeUpdate() method, for running SQL statements that do not return results, such as the
UPDATE and DELETE statements. executeUpdate() returns an integer that indicates the number of rows
in the database that were altered.
If you don't know whether a SQL statement is going to return results (such as when the user is entering the
statement in a form field), you can use the execute() method of Statement. This method returns true if there
is a result associated with the statement. In this case, the ResultSet can be retrieved using the getResultSet()
method and the number of updated rows can be retrieved using getUpdateCount():
Statement stmt = con.createStatement(); if(stmt.execute(sqlString))//sqlString is any sql query
{
ResultSet rs = stmt.getResultSet(); // display the results
}
else { System.out.println("Rows updated: " + stmt.getUpdateCount());
}
It is important to remember that a Statement object represents a single SQL statement. A call to
executeQuery(), executeUpdate(), or execute() implicitly closes any active ResultSet associated with the
Statement. In other words, you need to be sure you are done with the results from a query before you
execute another query with the same Statement object. If your application needs to execute more than one
simultaneous query, you need to use multiple Statement objects. As a general rule, calling the close()
method of any JDBC object also closes any dependent objects, such as a Statement generated by a
Connection or a ResultSet generated by a Statement, but well−written JDBC code closes everything
explicitly.
2)Prepared Statements
The PreparedStatement object is a close relative of the Statement object. Both accomplish roughly the same
thing: running SQL statements. PreparedStatement, however, allows you to precompile your SQL and run
it repeatedly, adjusting specific parameters as necessary. Since processing SQL strings is a large part of a
database's overhead, getting compilation out of the way at the start can significantly improve performance.
As with Statement, you create a PreparedStatement object from a Connection object. In this case, though,
the SQL is specified at creation instead of execution, using the prepareStatement() method ofConnection:
This SQL statement inserts a new row into the EMPLOYEES table, setting the NAME and PHONE
columns to certain values. Since the whole point of a PreparedStatement is to be able to execute the
statement repeatedly, we don't specify values in the call to prepareStatement(), but instead use question
marks (?) to indicate parameters for the statement. To actually run the statement, we specify values for the
parameters and then execute the statement:
The CallableStatement interface is the JDBC object that supports stored procedures.
A stored procedure is a prepared SQL code that you can save, so the code can be reused over and over
again. So if you have an SQL query that you write over and over again, save it as a stored procedure, and
then just call it to execute it. You can also pass parameters to a stored procedure, so that the stored
procedure can act based on the parameter value(s) that is passed.
Stored Procedure syntax
{call procedure_name[(?[,?...])]}
{? = call procedure_name[(?[,?...])]}
Eample:
CallableStatment cstmt = con.prepareCall("{call sp_interest()}");
Here sp_interest() is a stored procedure
JDBC Architecture
Different database systems have something in common: a similar purpose and a mostly compatible query
language. Every database has its own API. JDBC is Sun's attempt to create a platform−neutral interface
between databases and Java. The JDBC API defines a set of interfaces that encapsulate major database
functionality, including running queries, processing results. Following figure shows how an application
uses JDBC to interact with one or more databases without knowing about the underlying driver
implementations.
Common JDBC components
DriverManager: this class manages a list of database drivers. Matches connection request from the
java application with the proper database driver using communication sub protocol. The first driver
that recognizes a certain sub protocol under JDBC will be used to establish a database connection.
Driver: This interface handles the communication with the database server. We rarely interact
directly with Driver, instead we use a DriverManager object which manage objects of this type. It
also abstracts the details associated with working with Driver objects.
Connection: This interface with all methods for contacting a database. The connection object
represents communication context, i.e., all communication with database is through connection
object only.
Statement: We use objects created from this interface to submit the SQL statement to the database.
Some interfaces accept parameters in addition to executing stored procedures.
ResultSet: These objects hold data retrieved from a database after we execute an SQL query using
statement object. It act as an iterator to move through its data.
SQLException: This clas handles any errors that occur in a database application.
Given below is simple example that incorporates most of the major pieces of JDBC functionality. It loads a
driver, connects to the database, executes some SQL, and retrieves the results.
import java.sql.*;
public class JDBCSample
{
public static void main(String args[]) {
try
{
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("jdbc:mysql://localhost/emp","root","");
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT * FROM EMPLOYEES");
while(rs.next())
{
System.out.println(rs.getString(1));
}
rs.close(); stmt.close(); con.close();
}
}
JDBC Drivers
JDBC drivers are available for most database platforms, from a number of vendors and in a
number of different flavors.
Type 1 drivers use a bridge technology to connect a Java client to an ODBC database system. The
JDBC−ODBC Bridge from Sun and InterSolv is the only extant example of a Type 1 driver. Type 1
drivers require some sort of non−Java software to be installed on the machine running your code,
and they are implemented using native code.
The JDBC-ODBC bridge driver uses ODBC driver to connect to the database. The JDBC-ODBC
bridge driver converts JDBC method calls into the ODBC function calls.
Advantages:
easy to use.
can be easily connected to any database.
Disadvantages:
Performance degraded because JDBC method call is converted into the ODBC function calls.
The ODBC driver needs to be installed on the client machine.
Type 2 Native−API Partly Java Drivers
Type 2 drivers use a native code library to access a database, wrapping a thin layer of Java around the
native library.
The Native API driver uses the client-side libraries of the database. The driver converts JDBC method
calls into native calls of the database API. It is not written entirely in java.
Advantage:
performance upgraded than JDBC-ODBC bridge driver.
Disadvantage:
The Native driver needs to be installed on the each client machine.
The Vendor client library needs to be installed on client machine.
The Network Protocol driver uses middleware (application server) that converts JDBC calls directly or
indirectly into the vendor-specific database protocol. It is fully written in java.
Advantage:
No client side library is required because of application server that can perform many tasks like
auditing, load balancing, logging etc.
Disadvantages:
Network support is required on client machine.
Requires database-specific coding to be done in the middle tier.
Maintenance of Network Protocol driver becomes costly because it requires database-specific coding
to be done in the middle tier.
Advantage:
Disadvantage:
if(rs.wasNull())
System.out.println("Result was null");
else
System.out.println("In Stock: " + numberInStock);
We can use getObject() and test whether the result is null.
Large Data Types
We can retrieve large chunks of data from a ResultSet as a stream. This can be useful when reading images
from a database or loading large documents from a data store. The relevant ResultSet methods are
getAsciiStream(), getBinaryStream(), and getUnicodeStream(), where each method has column name and
column index variants. Each of these methods returns an InputStream.
Eg: Here's a sample code that retrieves an image from a PICTURES table and writes the image to an
OutputStream of some kind.
ResultSet rs=stmt.executeQuery("select image from pictures where pid="+req.
getparameter("pid"));
The JDBC 2.0 API includes BLOB and CLOB objects to handle large data types. Binary large objects
(BLOBs) and character large objects (CLOBs) store large amounts of binary or character data. JDBC 1.0
makes programs retrieve BLOB and CLOB data using the getBinaryStream() or getAsciiStream() methods.
In JDBC 2.0, the ResultSet interface includes getBlob() and getClob() methods, which return BLOB and
CLOB objects, respectively. The BLOB and CLOB objects themselves allow access to their data via streams
(the getBinaryStream() method of BLOB and the getCharacterStream() method of CLOB). We can set
BLOB and CLOB objects when we are working with a PreparedStatement, using the setBlob() and setClob()
methods. The lifespan of a Blob or Clob object is limited to the transaction that created it.
Handling Errors
Any JDBC object that encounters an error that halts execution throws a SQLException. The SQLException
class extends the normal java.lang.Exception class and defines an additional method called
getNextException(). This allows JDBC classes to chain a series of SQLException objects together.
SQLException also defines the getSQLState(), getMessage() and getErrorCode() methods to provide
additional information about an error. getSQLState(): The value returned by getSQLState() is one of the
SQL state codes. The following are certain SQL State Codes:
SQL State Code Definition
00 Successful completion
01 Warning
02 No data
07 Dynamic SQL error
printWarnings(stmt.getWarnings());
printWarnings(rs.getWarnings());
Metadata
Most JDBC programs are designed to work with a specific database and particular tables in that database;
the program knows exactly what kind of data it is dealing with. Some applications, however, need to
dynamically discover information about resultSet structures or underlying database configurations. This
information is called metadata, and JDBC provides two classes for dealing with it: DatabaseMetaData and
ResultSetMetaData.
1. DatabaseMetaData
We can retrieve general information about the structure of a database with the java.sql.DatabaseMetaData
interface. Database metadata is associated with a particular connection, so DatabaseMetaData objects are
created with the getMetaData() method of Connection:
DatabaseMetaData dbmeta = con.getMetaData();
DatabaseMetaData provides a number of methods that can be used to get configuration information about
the database such as database product name, product version, driver name etc. some of the methods in
DatabaseMetaData interface are String getDriverName()- return the name of the JDBC driver
String getDriverVersion()- return the version number of the JDBC driver String
getUserName()- return the user name
String getDatabaseProductName()- return the product name of the database
Eg:
import java.sql.*;
public class DBViewer {
public static void main(String[] args) {
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con= DriverManager.getConnection("jdbc:mysql://localhost/emp","root",""");
DatabaseMetaData dbmd = con.getMetaData();
System.out.println("Driver Name: " + dbmd.getDriverName());
System.out.println("Driver Version: " + dbmd.getDriverVersion());
System.out.println("Database Product: " + dbmd.getDatabaseProductName());
con.close();
}
catch (ClassNotFoundException e)
{ System.out.println("Unable to load database driver class");}
catch (SQLException e) {
System.out.println("SQL Exception: " + e.getMessage());
}
} }
2. ResultSetMetaData
The ResultSetMetaData interface provides information about the structure of a particular ResultSet with the
java.sql.ResultSetMetaData interface. ResultSetMetaData is associated with a particular connection, so
ResultSetMetaData objects are created with the getMetaData() method of Connection.
ResultSetMetaData rsmd=con.getMetaData();
Data provided by ResultSetMetaData includes the number of available columns, the names of those
columns, and the type of data available in each column. The methods of ResultSetMetaData interface are:
int getColumnCount(): returns total number of columns in the ResultSet
String getColumnLabel(int index):return column name of the specified column index String
Method Function
first() Move to the first record.
last() Move to the last record.
next() Move to the next record.
previous() Move to the previous record.
beforeFirst() Move to immediately before the first record.
afterLast() Move to immediately after the last record.
absolute(int) Move to an absolute row number. Takes a positive or negative argument.
relative(int) Move backward or forward a specified number of rows. Takes a positive
or negativeargument.
The JDBC includes a number of methods that tells about the position of cursor in a
ResultSet. They include:
isFirst(): return true if the cursor is located on the first record.
isLast(): return true if the cursor is located on the last record.
isAfterLast(): returns true if the cursor is after the last row in the result set.
isBeforeFirst(): returns true if the cursor is before the first row in the result set .
With an updateable ResultSet, we can change data in an existing row, insert an entirely new
row, or delete an existing row. To change data in an existing row, we use the updateXXX()
methods of ResultSet, where XXX represent a data type in java. Eg:
Transactions
A transaction is a group of several operations that must behave atomically, or as if they are a
single, indivisible operation. With regards to databases, transactions allow to combine one or
more database actions into a single atomic unit.Working with a transaction involves the
following steps:
1. Start the transaction
2. Perform its component operations
3. Either commit the transaction if all the component operations succeed or roll it back
if one of the operations fails.
The ability to roll back a transaction is the key feature. This means that if any one SQL
statement fails, the entire operation fails, and it is as though none of the component
operations took place.
The Connection object in JDBC is responsible for transaction management. By default, a
new connection starts out in transaction auto−commit mode, which means that every SQL
statement is executed as an individual transaction that is immediately committed to the
database.