4.1 Java Database Programming
4.1 Java Database Programming
A database system consists of a database, the software that stores and manages data in the
database, and the application programs that present data and enable the user to interact with the
database system. Almost all the current applications that we use require a database management
system at backend inorder to handle the data associated with the application. When you purchase a
database system, such as MySQL, Oracle, IBM, Microsoft, or Sybase, from a software vendor, you
actually purchase the software comprising a database management system (DBMS).All Data Base
systems make use of the universal query language SQL(Standard Query language) for manipulating
and accessing data associated with them.
Different database systems have surprisingly little in common: just a similar purpose and
a mostly compatible query language. Beyond that, every database has its own API that you must learn
to write programs that interact with the database. So writing code capable of interfacing with
databases from more than one vendor was a great challenge.
Since nearly all relational database management systems (RDBMSs) support SQL, and
because Java itself runs on most platforms, JDBC makes it possible to write a single database
application that can run on different platforms and interact with different DBMSs.. Only thing we
need to do is to make use of the driver which is specific to the database used at the backend.
In short JDBC helps the programmers to write java applications that manage these three
programming activities:
The set of classes that implements the JDBC interfaces for a particular database engine is called a
JDBC Driver. JDBC Drivers are written by vendors and must support the basic features of the
JDBC specification ie, JDBC drivers should implement interfaces and classes defined by the JDBC
API for a particular DBMS vendor. It serves as the interface to facilitate communications between
JDBC
and a proprietary database. It processes JDBC methods invocations, sends SQL statements to a specific
data source, and returns results back to the application. It translates and/or optimizes requests so the
request conforms to the syntax supported by the specific DBMS providing database independence.. If the
back- end database changes, only JDBC driver need to be replaced.
This drivers use a bridge technology to access a database. It provides a gateway to the ODBC
API. ODBC is a proprietary format developed by Microsoft that enables communication between
databases clients running on Windows and DBMS available on the market.
Since there are different types of databases and each of them has its own way of dealing with SQL
queries and to return the results, ODBC provides identical results regardless of the type of database,
without the need for you to configure the program that sends the request. This is an advantage
becauseODBC drivers exist for many Relational Database Management System (RDBMS) platforms
This driver is included in the Java 2 SDK within the sun.jdbc.odbc package and it translates JDBC
method calls into ODBC function calls and sends them to the ODBC driver. The Bridge implements
JDBC for any database for which an ODBC driver is available.
In order to use Type 1 drivers ODBC must be installed on the computer having the driver
and the database which is being connected to must support an ODBC driver. This is platform-
dependent as it makes use of ODBC which in turn depends on native libraries of the operating system.
Applications that make use of this driver cause performance overhead since the calls have to go
through the JDBC overhead bridge to the ODBC driver, then to the native db connectivity interface.
Type 1 drivers are not suitable for developing web applications as they need software to be installed on
client machine
When Java first came out, this was a useful driver because most databases only supported
ODBC access but now this type of driver is recommended only for experimental use or when no other
alternative is available.
4.1.2.2 TYPE 2 - JDBC-NATIVE BRIDGE
Type 2 drivers use the Java Native Interface (JNI) to make calls to a local
database library API. This driver converts the JDBC calls into a database specific call for databases
such as SQL, ORACLE etc i.e. this driver is specific to a particular database. This driver
communicates directly with the database server and requires some native code to connect to the
database. These drivers typically provided by the database vendors and used in the same manner as
the JDBC-ODBC Bridge, the vendor-specific driver must be installed on each client machine. If we
change the Database we have to change the native API driver as it is specific to a database. Since
Native API must be installed in the Client System type 2 drivers cannot be used for the Internet. The
distinctive characteristic of type 2 jdbc drivers are that they are typically offer better performance
than the JDBC-ODBC Bridge as the layers of communication (tiers) are less than that of Type1
Type3 drivers provide a client with a generic network API that is then translated into
database specific access at the server level. The JDBC type 3 driver, also known as the network-
protocol driver is a database driver implementation which makes use of a middle-tier between the
calling program and the database. The middle-tier (application server) converts JDBC calls directly or
indirectly into the vendor-specific database protocol. Type 3 database requests are passed through the
network to the middle-tier server and the middle-tier server can in turn use Type1, Type 2 or Type 4
drivers to translate the request to the database. Since the communication between client and the
middleware server is database independent, there is no need for the vendor db library on the client
machine.
This driver is very flexible as it allows access to multiple databases using one driver .The
number of data bases that can be accessed depends on the number of databases the middleware has
been configured to support. Type 3 driver is suitable for developing web applications since there is no
client side software needed. One of the disadvantages of this driver is that database-specific coding
should be done in the middle tier.
If you are accessing one type of database, such as Oracle, Sybase, or IBM, the preferred driver type is
4.
If your Java application is accessing multiple types of databases at the same time, type 3 is the
preferred driver.
Type 2 drivers are useful in situations where a type 3 or type 4 driver is not available yet for your
database.
The type 1 driver is not considered a deployment-level driver and is typically used for development
and testing purposes only.
The java.sql package contains the entire set of interfaces and classes defined by JDBC
API that sends SQL (Structured Query Language) statements to relational databases and retrieves the
results of executing those SQL statements.
(Fig: 4.6) Java.sql Package
The cornerstone of the JDBC package is the DriverManager class. This class keeps track
of all the different available database drivers. The DriverManager manages loading and unloading
drivers. The DriverManager maintains a Vector that holds information about all the drivers that it
knows about. The elements in the Vector contain information about the driver such as the class name
of the Driver object, a copy of the actual Driver object, and the Driver security context. The
DriverManager, while not a static class, maintains all static instance variables with static access
methods for registering and unregistering drivers.
METHODS:
public static Driver getDriver(String URL) throws SQLException- Finds a driver that
understands the JDBC URL from the registered driver list
The Date class is used to represent dates in the SQL format YYYY-MM-DD. It contains methods to
perform conversions of java.util.Date and the SQL DATE type
METHODS
public static Date valueOf (String str)-Converts a String str to an sql.Date object
The Time class is used to represent times in the SQL format HH:MM:SS. It contains methods to
perform SQL TIME type and Java Time object conversions.
METHODS:
public String toString()-Returns a String with the Time formatted this way: HH:MM:SS
public static Time valueOf(String numStr)-Returns a Numeric object from the String numStr
parameter that is in the format: HH:MM:SS
4.1.3.4 TIMESTAMP
The Timestamp class is used to represent a combination of date and time values in the ANSI SQL
format YYYY-MMDD HH:MM:SS.F
METHODS:
public boolean equals(Timestamp tstamp) Compares the Timestamp object with the Timestamp
parameter tstamp; returns true if they match
The Driver is the software wedge that communicates with the platform-dependent
database, either directly or using another piece of software. How it communicates really depends on
the database, the platform, and the implementation. So All JDBC Drivers must implement the Driver
interface and each driver should supply a class that implements the Driver interface.
jdbc:<sub-protocol>:<sub-name> , where
sub-protocol is the name of the driver set that defines a particular database connectivity method. This
can be represented by several drivers.
sub-name is the additional information necessary to complete the URL. This information is different
depending on the sub-protocol.
Eg:String url = “jdbc:odbc:mysource”;
Using the getConnection() method, the DriverManager asks each driver that has
registered with it whether the database connection URL is valid. If one driver responds positively, the
DriverManager assumes a match. If no driver responds positively, an SQLException is thrown. The
DriverManager returns the error "no suitable driver," which means that of all the drivers that the
DriverManager knows about, not one of them could figure out the URL you passed to it.
The following methods can be used to easily navigate the results a query returns:
boolean getMoreResults()
This moves to the next result set in the Statement. This, like the execute() method, returns true if the
next result is a result set or false if it is an integer. If you have already retrieved a ResultSet from the
Statement, this method will close it before returning.
ResultSet getResultSet()
This method returns to you a result set in a ResultSet object. This result set is the current result set.
int getUpdateCount()
This method returns to you the integer result that an execute() method returned.
The SQL statements that read data from a database query return the data in a result set.
The SELECT statement is the standard way to select rows from a database and view them in a result
set. The java.sql.ResultSet interface represents the result set of a database query A ResultSet object
maintains a cursor that points to the current row in the result set. When a ResultSet object is created,
its position is always before the first row of data contained within the ResultSet. The methods of the
ResultSet interface can be broken down into three categories:
NAVIGATIONAL METHODS:
A ResultSet provides access to a table of data generated by executing a Statement. The table rows are
retrieved in sequence and it maintains a cursor pointing to its current row of data. There are
several methods in the ResultSet interface that involve moving the cursor. When you've retrieved all
the data you can from a column, it is time to move on to the next row. Moving to the next row is
done with the next() method. This method returns a boolean value indicating the status of the
row. Internally, it moves the ResultSet's cursor to the next row, thereby giving access to the data
stored in the columns of that row.
public boolean next()-Moves the cursor to the next row. This method returns false if there are no
more rows in the result set. The first call to next() makes the first row available to your program
public boolean previous()-Move one row backward direction.
public Boolean first()-Move to first row .
public int getRow()-Returns the row number that the cursor is pointing to
public boolean absolute(int row) -Moves the cursor to the specified row.
public boolean relative(int row)-Moves the cursor the given number of rows forward or backwards
from where it currently is pointing.
The ResultSet interface contains dozens of methods for getting the data of the current
row. There is a get method for each of the possible data types, and each get method has two versions:
one that takes in a column name, and one that takes in a column index.
For example, if the column you are interested in viewing contains an int, you need to use one of the
getInt() methods of ResultSet:
public int getInt(String columnName)-Returns the int in the current row in the column named
columnName.
public int getInt(int columnIndex) -Returns the int in the current row in the specified column index.
The column index starts at 1, meaning the first column of a row is 1, the second column of a row is 2,
and so on.
There are get methods in the ResultSet interface for each of the eight Java primitive types, as well as
common types such as java.lang.String and java.lang.Object. There are also methods for getting SQL
data types java.sql.Date, java.sql.Time, java.sql.TimeStamp.
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 update methods for each data type: one that uses the
column name and one that uses the column index. For example, to update a String column of the
current row of a result set, you would use one of the following updateString() methods:
public void updateString(int columnIndex, String s) -Changes the String in the specified column
to the value of s.
public void updateString(String columnName, String s)-Similar to the previous method, except
that the column is specified by its name instead of its index.
There are update methods for the eight primitive data types, as well as String and the SQL data types
in the java.sql package.
Updating a row in the result set changes the columns of the current row in the ResultSet object, but
not in the underlying database. To update your changes to the row in the database, you need to invoke
the following method:
public void updateRow()-Updates the current row by updating the corresponding row in the
database.
For example, the following prepared statement inserts a new row in a table called Employees:
This prepared statement contains four parameters. When the Prepared- Statement object is created
using the Connection object, this statement is sent to the database and precompiled, allowing the
database to execute the statement at a faster rate.
Connection Interface, contains different methods for creating a PreparedStatement. The method
public PreparedStatement prepareStatement(String sql) creates a prepared SQL statement. The
SQL is sent to the database for precompilation.
Each question mark in a prepared statement denotes a parameter. The order in which the parameters
appear determines their index, with the first parameter being index 1, the second parameter index 2,
and so on. This is important when you go to set the values using the various set methods in the
PreparedStatement interface.
Use the appropriate set methods of the PreparedStatement interface to set each of the
parameters of the prepared statement.
Before a prepared statement can be executed, each of its parameters must be assigned a value. The
PreparedStatement interface contains a set method for each of the possible data types of a
parameter. Each set method takes in an index to denote which parameter to set. For example, if the
data type of the parameter is a double, then you use the method.
Eg: The following statements prepare a statement and assign each of its four parameters a value using
the appropriate set method:
PreparedStatement insert =
connection.prepareStatement(“INSERT INTO Employees VALUES (?, ?, ?, ?)”);
insert.setDouble(2, 2.50);
insert.setInt(1, 103);
insert.setString(3, “George”);
insert.setString(4, “Washington”);
Notice that the order in which you set the parameters does not matter, as long as you set a
value for each parameter of the prepared statement.
Invoke one of the execute() methods of the PreparedStatement interface to execute the
statement.
After the values of all the parameters are set, the prepared statement is executed using one of the
following methods in the PreparedStatement interface:
public ResultSet executeQuery()-Use this method if the SQL statement returns a result set, like a
SELECT statement.
public int executeUpdate()-Use this method for statements like INSERT, UPDATE, or DELETE.
The return value is the number of rows affected.
public boolean execute()-This method executes any type of SQL statement. Use the getResultSet()
method to obtain the result set if one is created
This is the primary interface to access stored procedures on a database. A stored procedure
allows you to repeat a sequence of tasks repeatedly in an efficient manner, much like writing a
method in Java. Use one of the prepareCall() methods of the Connection interface to create a
CallableStatement object:
public CallableStatement prepareCall(String sql)-Creates a callable statement using the given
SQL statement
Following are the different steps involved in using JDBC to access a database
1. importing java.sql
java.sql package contains all the classes and interfaces we need to create and manage a
data base connection. Inorder to make use of these classes and interfaces we need to import them in
our program
In this step of the jdbc connection process, we load the driver class by calling
Class.forName() with the Driver class name as an argument. Once loaded, the Driver class creates an
instance of itself. A client can connect to Database Server through JDBC Driver. Since most of the
Database servers support ODBC driver therefore JDBC-ODBC Bridge driver is commonly used. The
return type of the Class.forName (String ClassName) method is “Class”. Class is a class in java.lang
package.
try
{
Class.forName(”sun.jdbc.odbc.JdbcOdbcDriver”); //Or any other driver
}
catch(Exception x)
{
System.out.println( “Unable to load the driver class!” );
}
3. Connecting to DBMS
The JDBC DriverManager class defines objects which can connect Java applications to a
JDBC driver. DriverManager is considered the backbone of JDBC architecture. DriverManager class
manages the JDBC drivers that are installed on the system. Its getConnection() method is used to
establish a connection to a database. It uses a username, password, and a jdbc url(that represents the
name of the data source) to establish a connection to the database and returns a connection object. A
jdbc Connection represents a session/connection with a specific database. Within the context of a
Connection, SQL, PL/SQL statements are executed and results are returned. An application can have
one or more connections with a single database, or it can have many connections with different
databases. A Connection object provides metadata i.e. information about the database, tables, and
fields. It also contains methods to deal with transactions.
All JDBC URLs start with jdbc. The subprotocol is actually determined by the driver you
are using. The subname can contain additional information used by the satisfying subprotocol
(i.e.driver), such as the location of the data source, as well as a port number
EXAMPLE:
This method returns a Connection interface that is used throughout the process to reference the
database.
4. Creating a jdbc Statement object
Once a connection is obtained we can interact with the database. Connection interface defines
methods for interacting with the database via the established connection. To execute SQL statements,
you need to instantiate a Statement object from your connection object by using the createStatement()
method.
A statement object is used to send and execute SQL statements to a database. There are three
kinds of Statements
EXAMPLE:
EXAMPLE:
Statement interface defines methods that are used to interact with database via the
execution of SQL statements. The Statement class has three methods for executing statements:
executeQuery(), executeUpdate(), and execute(). For a SELECT statement, the method to use is
executeQuery . For statements that create or modify tables, the method to use is executeUpdate. Note:
Statements that create a table, alter a table, or drop a table are all examples of DDL statements and
are executed with the method executeUpdate(). execute() executes an SQL statement that is written
as String object.
EXAMPLE:
A result set provides access to a table of data generated by executing a Statement. The
table rows are retrieved in sequence. A ResultSet maintains a cursor pointing to its current row of
data. The next() method is used to successively step through the rows of the tabular results. Within a
row,ResultSet provides various getXxx methods that take a column index or column name as an
argument and return the result as a variety of different Java types and the the first column in a
ResultSet row has index 1.
EXAMPLE:
while(resultSet.next())
{
System.out.println(results.getString(1) + " " + results.getString(2) + " ” +results.getString(3));
}
7. Close connection
We should postpone this step if we expect to perform additional database operations, since the
overhead of opening a connection is usually large. In fact, reusing existing connections is such an
important optimization.
import java.sql.*
while (rs.next())
System.out.println("Name= " + rs.getString("moviename") + " Date= " +
rs.getString("releasedate");
}
catch (SQLException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
finally
{
// Close the connection
con.close();
}
}