
Practical Database Programming With Java
.pdf
Homework 87
9.The data type VARCHAR2 in Oracle database is a string variable with _______
a.Limited length
b.Fixed length
c.Certain number of letters
d.Varying length
10.For data tables in Oracle Database 10g XE, a blank field must be ________
a.Indicated by NULL
b.Kept as a blank
c.Either by NULL or a blank
d.Avoided
III. Exercises
1.What are the advantages to using an integrated database approach over that of a file processing approach?
2.Define entity integrity and referential integrity. Describe the reasons for enforcing these rules.
3.Entities can have three types of relationships. It can be one-to-one, one-to-many, and many-to- many. Define each type of relationship. Draw ER diagrams to illustrate each type of relationship.
4.List all steps to create Foreign keys between data tables for SQL Server database in the SQL Server Management Studio Express. Illustrate those steps by using a real example. For instance, how to create foreign keys between the LogIn and the Faculty table.
5.List all steps to create Foreign keys between data tables for Oracle database in the Oracle Database 10g XE. Illustrate those steps by using a real example. For instance, how to create foreign keys between the StudentCourse and the Course table.

Chapter 3
JDBC API and JDBC Drivers
This chapter discusses the fundamentals of JDBC and JDBC API, which include an overview of the JDBC and JDBC API, JDBC drivers, and related components used in JDBC API.
3.1 WHAT ARE JDBC AND JDBC API?
JDBC is a standard Java Database Connectivity, and JDBC API can be considered as a
Java Database Connectivity Application Programming Interface (JDBC API). All components and techniques of JDBC are embedded and implemented in JDBC API. Basically, the JDBC API is composed of a set of classes and interfaces used to interact with databases from Java applications.
Generally, the JDBC API performs the following three functions:
1.Establish a connection between your Java application and related databases
2.Build and execute SQL statements
3.Process the results
Different database vendors provide various JDBC drivers to support their applications to different databases. The most popular JDBC components are located at the following packages:
•java.sql: contains the standard JDBC components
•javax.sql: contains the Standard Extension of JDBC, which provides additional features, such as Java Naming and Directory Interface (JNDI) and Java Transaction Service
(JTS).
•oracle.jdbc: contains the extended functions provided by the java.sql and javax.sql interfaces.
•oracle.sql: contains classes and interfaces that provide Java mappings to SQL data types.
All of these parts are combined together to provide necessary components and classes to build database applications using Java.
Practical Database Programming with Java, First Edition. Ying Bai.
© 2011 the Institute of Electrical and Electronics Engineers, Inc. Published 2011 by John Wiley & Sons, Inc.
89

90 Chapter 3 JDBC API and JDBC Drivers
Generally, JDBC API enables users to access virtually any kind of tabular data source, such as spreadsheets or flat files from a Java application. It also provides connectivity to a wide scope of SQL or Oracle databases. One of the most important advantages of using JDBC is that it allows users to access any kind of relational database in a same coding way, which means that the user can develop one program with the same coding to access either a SQL Server database or an Oracle database, or MySQL database without coding modification.
The JDBC 3.0 and JDBC 4.0 specifications contain additional features, such as extensions to the support to various data types, MetaData components, and improvements on some interfaces.
3.2 JDBC COMPONENTS AND ARCHITECTURE
The JDBC API is the only part of the entire JDBC product line.
The core of JDBC API is called a JDBC driver, which implements all JDBC components, including the classes and interfaces, to build a connection and manipulate data between your Java application and selected database. Exactly a JDBC driver, which is a class that is composed of a set of methods, builds a connection and accesses databases through those methods.
The JDBC API contains two major sets of interfaces: the first is the JDBC API for application writers (interface to your Java applications), and the second is the lower-level JDBC driver API for driver writers (interface to your database). JDBC technology drivers fit into one of four categories. Applications and applets can access databases via the JDBC API using pure Java JDBC technology-based drivers, as shown in Figure 3.1.
As we mentioned, the JDBC API is composed of a set of classes and interfaces used to interact with databases from Java applications. Table 3.1 lists all classes defined in the JDBC API and their functions, and Table 3.2 shows all interfaces defined in the JDBC API.
Java
Application
JDBC API
JDBC Driver
Manager or
DataSource
Pure Java
JDBC Driver
Database
Server
Figure 3.1. The components and architecture of a JDBC API.

|
3.2 JDBC Components and Architecture 91 |
Table 3.1. Classes defined in the JDBC API |
|
|
|
Classes |
Function |
|
|
DriverManager |
Handle loading and unloading of drivers and establish a connection to a |
|
database |
DriverPropertyInfo |
All methods defined in this class are used to setup or retrieve properties |
|
of a driver. The properties can then be used by the Connection object to |
|
connect to the database |
Type |
The Type class is only used to define the constants used for identifying of |
|
the SQL types |
Date |
This class contains methods to perform conversion of SQL date formats |
|
and Java Date objects |
Time |
This class is similar to the Date class, and it contains methods to convert |
|
between SQL time and Java Time object |
TimeStamp |
This class provides additional precision to the Java Date object by adding |
|
a nanosecond field |
|
|
Table 3.2. Interfaces defined in the JDBC API
Interface |
Function |
|
|
Driver |
The primary use of the Driver interface is to create the Connection |
|
objects. It can also be used for the collection of JDBC driver meta data |
|
and JDBC driver status checking |
Connection |
This interface is used for the maintenance and status monitoring of a |
|
database session. It also provides data access control through the use of |
|
transaction locking |
Statement |
The Statement methods are used to execute SQL statements and retrieve |
|
data from the ResultSet object |
PreparedStatement |
This interface is used to execute precompile SQL statements. Precompile |
|
statements allow for faster and more efficient statement execution, and |
|
more important, it allows running dynamic query with querying |
|
parameters’ variation. This interface can be considered as a subclass of |
|
the Statement |
CallableStatement |
This interface is mainly used to execute SQL stored procedures. Both IN |
|
and OUT parameters are supported. This interface can be considered as |
|
a subclass of the Statement |
ResultSet |
The ResultSet object contains the queried result in rows and columns |
|
format. This interface also provides methods to retrieve data returned by |
|
an SQL statement execution. It also contains methods for SQL data type |
|
and JDBC data type conversion |
ResultSetMetaData |
This interface contains a collection of metadata information or physical |
|
descriptions associated with the last ResultSet object |
DatabaseMetaData |
This interface contains a collection of metadata regarding to the database |
|
used, including the database version, table names, columns, and |
|
supported functions |
|
|

92 Chapter 3 JDBC API and JDBC Drivers
It can be found from Table 3.1 that the most popular classes in JDBC API are top three classes: DriverManager, DriverPropertyInfo, and Type, and they are widely implemented in the Java database programming applications.
All interfaces listed in Table 3.2 are popular and widely implemented in the Java database applications. More detailed discussion and example applications of these interfaces will be provided in Chapter 6 with real project examples.
The core of the JDBC API is the JDBC Driver that can be accessed and called from the DriverManager class method. Depends on the different applications, a JDBC driver can be categorized into four types: Type I, Type II, Type III, and Type IV. A more detailed discussion about the JDBC Driver and its types will be given in Section 3.4. An optional way to access the database is to use the DataSource object, which is a better way to identify and connect to a data source, and makes code even more portable and easier to maintain.
3.3 HOW DOES JDBC WORK?
As we mentioned in the last section, the JDBC API has three functions: (1) setup a connection between your Java application and your database; (2) build and execute SQL statements; and (3) process results. We will discuss these functions in more details in this section based on the JDBC architecture shown in Figure 3.1.
3.3.1 Establish a Connection
JDBC Driver class contains six methods, and one of the most important methods is the connect() method, which is used to connect to the database. When using this Driver class, a point to be noted is that most methods defined in the Driver class never be called directly; instead, they should be called via the DriverManager class methods.
3.3.1.1 Using DriverManager to Establish a Connection
The DriverManager class is a set of utility functions that work with the Driver methods together and manage multiple JDBC drivers by keeping them as a list of drivers loaded. Although loading a driver and registering a driver are two steps, only one method call is necessary to perform these two operations. The operational sequence of loading and registering a JDBC driver is:
1.Call class methods in the DriverManager class to load the driver into the Java interpreter.
2.Register the driver using the registerDriver() method.
When loaded, the driver will execute the DriverManager.registerDriver() method to register itself. The above two operations will never be performed until a method in the DriverManager is executed, which means that even both operations have been coded in an application; however, the driver cannot be loaded and registered until a method such as connect() is first executed.
To load and register a JDBC driver, two popular methods can be used:
1.Use Class.forName() method:
Class.forName(“com.microsoft.sqlserver.jdbc.SQLServerDriver”);

3.3 How Does JDBC Work? 93
2.Create a new instance of the Driver class: Driver sqlDriver = new com.microsoft. sqlserver.jdbc.SQLServerDriver;
Relatively speaking, the first method is more professional, since the driver is both loaded and registered when a valid method in the DriverManager class is executed. The second method cannot guarantee that the driver has been registered by using the DriverManager.
3.3.1.2 Using DataSource Object to Establish a Connection
Another and better way to establish a connection is to use the DataSouce object.
The DataSource interface, introduced in the JDBC 2.0 Standard Extension API, is a better way to connect to a data source to perform data actions. In JDBC, a data source is a class that implements the interface javax.sql.DataSource to connect to more than one desired databases. The getConnection() method is always used to setup this connection.
A DataSource object is normally registered with a JNDI naming service. This means that an application can retrieve a DataSource object by name from the naming service independently of the system configuration.
Perform the following three operations to deploy a DataSource object:
1.Create an instance of the DataSource class
2.Set its properties using setter methods
3.Register it with a JNDI naming service
After a valid connection has been setup using the DataSource object, one can use any data query methods listed in Tables 3.3 and 3.4 to perform data actions against the desired database.
Table 3.3. The function of three SQL statements execution methods
Method |
Function |
|
|
executeQuery() |
This method performs data query and returns a ResultSet object that |
|
contains the queried results |
executeUpdate() |
This method does not perform data query, instead it only performs either a |
|
data updating, insertion, or deleting action against the database and returns |
|
an integer that equals to the number of rows that have been successfully |
|
updated, inserted, or deleted |
execute() |
This method is a special method, and it can be used either way. All different |
|
data actions can be performed by using this method, such as data query, |
|
data insertion, data updating, and data deleting. The most important |
|
difference between the execute() method and two above methods is that |
|
this method can be used to execute some SQL statements that are |
|
unknown at the compile time or return multiple results from stored |
|
procedures. Another difference is that the execute() method does not |
|
return any result itself, and one needs to use getResultSet() or |
|
getUpdateCount() method to pick up the results. Both methods belong to |
|
the Statement class |
|
|

94 Chapter 3 JDBC API and JDBC Drivers
Table 3.4. The desired method used to pick up the SQL execution results
Execution Method |
Picking up Method |
|
|
executeQuery() |
getResultSet(), getXXX(), where XXX equals to the desired data type of |
|
returned result |
executeUpdate() |
getUpdateCount() |
|
This method will returns an integer that equals to the number of rows that |
|
have been successfully updated, inserted, or deleted |
execute() |
getResultSet(), getUpdateCount() |
|
This method does not return any result itself, and one needs to use |
|
getResultSet() or getUpdateCount() method to pick up the results. Both |
|
methods belong to the Statement class |
|
|
3.3.2 Build and Execute SQL Statements
Once a valid connection is established and a Connection object is created, the JDBC driver is responsible for ensuring that an application has consistent and uniform access to any database. It is also responsible for ensuring that any requests made the application are presented to the database in a way that can be recognized by the database.
To build a SQL statement, one needs to call the method createStatement() that belongs to the Connection class to create a new Statement object. Regularly, there are three type of Statement objects widely implemented in the JDBC API: Statement, PreparedStatement, and CallableStatement. The relationship among these three classes is: the PreparedStatement and CallableStatement classes are the subclasses of the Statement class.
To execute a SQL statement, one of the following three methods can be called:
1.executeQuery()
2.executeUpdate()
3.execute()
All of these methods belong to the Statement and the PreparedStatement classes and used to access database to perform different data actions.
The differences between these three methods are dependents on the different data operations and actions.Table 3.3 lists the function for each method and the situation under which the appropriate method should be utilized. Mode-detailed discussion about these three methods and their implementations can be found in Section 6.4.2.3 in Chapter 6.
3.3.3 Process Results
After the desired SQL statement is executed, you need to retrieve the execution results.
Depends on the different execution methods you called, you need to use the different methods to pick up the results.
Table 3.4 lists some necessary methods used to pick up the appropriate results based on the different execution methods utilized.

3.4 JDBC Driver and Driver Types 95
3.3.3.1 Using ResultSet Object
A ResultSet object will be created after the executeQuery() method is executed or a getResultSet() method is executed. A ResultSet object is a data structure that presents rows and columns returned by a valid query. It maintains a cursor pointing to its current row of data. Initially, the cursor is positioned before the first row. One can use the next() method to move the cursor to the next row, and continue this moving one can scan the entire ResultSet.With a loop, one can use the appropriate getXXX() method of the ResultSet class to pick up each row in the ResultSet object. The XXX indicates the corresponding Java data type of the selected row. A more detailed discussion about these methods will be provided in Chapter 4.
3.3.3.2 Using RowSet Object
A RowSet object contains a set of rows from a result set or some other source of tabular data, like a file or spreadsheet. Because a RowSet object follows the JavaBeans model for properties and event notification, it is a JavaBeans component that can be combined with other components in an application. As is compatible with other Beans, application developers can probably use a development tool to create a RowSet object and set its properties.
RowSets may have many different implementations to fill different needs. These implementations fall into two broad categories, connected and disconnected:
1.A connected RowSet is equivalent to a ResultSet, and it maintains a connection to a data source as long as the RowSet is in use.
2.A disconnected RowSet works as a DataSet in Visual Studio.NET, and it can connect to a data source to perform the data updating periodically. Most time, it is disconnected with the data source and uses a mapping memory space as a mapped database.
While a RowSet is disconnected, it does not need a JDBC driver or the full JDBC API, so its footprint is very small. Thus, a RowSet is an ideal format for sending data over a network to a thin client.
Because it is not continually connected to its data source, a disconnected RowSet stores its data in memory. It needs to maintain metadata about the columns it contains and information about its internal state. It also needs a facility for making connections, for executing commands, and for reading and writing data to and from the data source. A connected RowSet, by contrast, opens a connection and keeps it open for as long as the RowSet is being used.
A more detailed discussion about the RowSet object and its implementation will be given in Sections 6.4.6.1 and 6.4.6.2 in Chapter 6.
Since the JDBC driver is a core for entire JDBC API, we will have a more detailed discussion about this component in the next section.
3.4 JDBC DRIVER AND DRIVER TYPES
The JDBC driver builds a bridge between your Java applications and your desired database, and works as an intermediate-level translator to perform a double-direction

96 Chapter 3 JDBC API and JDBC Drivers
conversion: convert your high-level Java codes to the low-level native codes to interface to the database, and convert the low-level native commands from the database to your high-level Java codes.
As we discussed in the last section, a JDBC driver class contains six method and one of the most important methods is the connect() method, which is used to connect to the database. When using this Driver class, a point to be noted is that most methods defined in the Driver class can never be called directly; instead, they should be called via the DriverManager class methods.
Generally, the JDBC API will not contain any JDBC driver, and you need to download a desired JDBC driver from the corresponding vendor if you want to use a specified driver. Based on the different configurations, JDBC drivers can be categorized into the following four types.
3.4.1 Type I: JDBC-ODBC Bridge Driver
Open Database Connectivity (ODBC) is a Microsoft-based database Application Programming Interface (API), and it aimed to make it independent of programming languages, database systems, and operating systems. In other words, the ODBC is a database and operating system independent API, and it can access any database in any platform without problem at all.
Figure 3.2 shows a typical architecture of JDBC-ODBC Bridge Driver application. Figure 3.2a is for a Java standard-alone application, and Figure 3.2b is a Java 2-tire application.
Basically, ODBC is built and based on various Call Level Interface (CLI) specifications from the SQL Access Group and X/Open techniques. To access an ODBC to interface to a desired database, a JDBC-ODBC Bridge is needed, and this bridge works just like a translator or a converter, that interprets the JDBC requests to the CLI in ODBC when a request is sent from the JDBC to the ODBC, and perform an inverse translation (from CLI in ODBC to JDBC) when a result is returned from the database. The advan-
Client
Java
Application Java
Application
JDBC-ODBC |
|
|
Bridge |
JDBC-ODBC |
|
|
Bridge |
|
ODBC Driver |
|
Database |
|
ODBC Driver |
|
|
Server |
|
|
|
|
Database |
|
|
Interface |
Network Interface |
|
|
|
(a) |
(b) |
Figure 3.2. |
JDBC-ODBC Bridge Driver. |

3.4 JDBC Driver and Driver Types 97
tage of using Type I driver is simplicity, since we do not need to know the details inside ODBC and transactions between the ODBC and DBMS. Refer to Figure 3.2a, it is a typical Java standalone application that uses JDBC-ODBC Bridge Driver to access a local database, and it will work fine. However, a problem will be exposed if applying this JDBC-ODBC Bridge Driver in a two-tier application that is shown in Figure 3.2b. The problem is that the network standard security manager will not allow the ODBC that is downloaded as an applet to access any local files when you build a Java Applet application to access a database located in a database server. Therefore, it is impossible to build a Java Applet application with this JDBC-ODBC Bridge Driver configuration.
3.4.2 Type II: Native-API-Partly-Java Driver
The Native-API-Partly-Java driver makes use of local native libraries to communicate with the database. The driver does this by making calls to the locally installed native call level interface (CLI) using a native language, either C or C++, to access the database. The CLI libraries are responsible for the actual communications with the database server. When a client application makes a database accessing request, the driver translates the JDBC request to the native method call and passes the request to the native CLI. After the database processed the request, results will be translated from their native language back to the JDBC and presented to the client application. Figure 3.3 shows a Type II driver configuration.
Compared with Type I driver, the communications between the driver and the database are performed by using the native CLI without needing any translation between JDBC and ODBC driver; therefore, the speed and efficiency of Type II driver is higher than that of Type I driver. When available, Type II drivers are recommended over Type I drivers.
3.4.3 Type III: JDBC-Net-All-Java Driver
Basically, the Type III drivers are similar with Type II drivers, and the only difference between them is the replacement of the native database access libraries.
Client
Java
Application
JDBC Driver
Local Disk
Native Database
Libraries (CLI) Database
Server
Network Interface
Figure 3.3. Type II Driver.