JDBC 4 is the forthcoming release of the Java Database Connectivity API.
Currently in Early Draft Review in the JCP (JSR 221), JDBC 4 is a major new
release with a strong focus on ease-of-use and programmer productivity. The new
JDBC version also introduces support for SQL 2003 data types, including SQL's
native XML type. This article surveys the key JDBC 4 features.

A large portion of data recorded on magnetic media is stored in some form of a
relational database. When the Java Database Connectivity API (JDBC) debuted in
1997, it made much of that data available to any Java application. JDBC
presented data stores in an object-oriented API that was easy to learn and use,
and it became an immediate success.

Version 4 of the JDCB API is currently in Early Draft Review in the JCP
(JSR 221)[1]. While prior JDBC versions
focused on incremental improvements providing functionality to J2EE application
servers, JDBC 4's key priority is to make it easier for developers to work
directly with the JDBC API. Thus, the latest JDBC spec is a return to the API's
roots, which was to provide a set of simple abstractions for developers who
needed to work with relational databases. Much of JDBC 4's ease-of-development
features are a direct result of new capabilities available in J2SE 1.5.

In addition to ease-of-use, JDBC 4 introduces several SQL 2003 features,
including a Java-specific mapping for the new XML SQL type. The new standard
also defines support for national character sets, and aims to enable JDBC
implementations to perform better by exposing to tools more information about
the state of database connections and statements. Once approved as final
standard, JDBC 4 will become a standard part of J2SE 1.6, and will supersede
JDBC 3. This article reviews those JDBC 4 features most likely to benefit
developers.

Better Pools

While JDBC did more than any other API to turn Java into the leading
enterprise platform, J2EE emerged in part to make working with enterprise data
more palatable to developers than what was possible with JDBC alone. Indeed,
JDBC's designers never intended their API to serve as the sole bridge to
enterprise databases from Java programs, but rather as a call-level interface
(CLI), on par with the X/Open standard, that other, higher-level APIs would
build on.

There are two key areas of JDBC complexity that J2EE vendors have invested
into solving for their customers: performance and ease of use. Because JDBC
data access occurs through the Connection interface, optimizing
the performance of that Connection and its associated artifacts is
key to higher JDBC performance. A common optimization technique reuses database
connections and objects representing SQL query or update statements. For such
connection and statement pools to work, JDBC had to evolve and standardize how
a runtime infrastructure interacts with connections and statements.

While JDBC provided abstractions for both connection and statement pooling,
those abstractions operated on a fairly coarse level. For instance, JDBC 3
connection pools merely substituted a pool of connections for a single
connection. Individual connections inside the pool were hard to manage,
especially if connections inside the pool became stale over time. That gave
rise to a situation where the entire database appeared unresponsive but, in
reality, the database server had no trouble, only the connection pool may have
run out of resources due to stale connections. The only solution was to
reinitialize the pool, sometimes by restarting the database server.

Because a stale connection does not necessarily mean a closed connection
(which might be garbage collected), connections that became unusable often took
up those valuable connection resources. A new method in JDBC 4's
Connection class, isValid(), allows a client to query
the database driver if a connection is still valid. This allows a more
intelligent management of connection pools by clients.

While one database connection is indistinguishable from another, the same
does not hold for statements: Some SQL statement are more frequently used than
others in any application domain. Prior to JDBC 4, there was no way to tell
such statements apart in a statement pooling environment. While every JDBC 4
PreparedStatement is poolable by default, the new
poolable property allows an application to offer a hint to the
statement pooler as to whether a statement should be pooled. This allows an
application developer, or a development tool, to better manage
statement-pooling resources, offering pooling preference to frequently accessed
statements.

Because a database is a shared resource, many Java applications require
concurrent access to the same data store. As each of those applications connect
to the database and execute statements on a connection, connections from some
applications might take up more resources than others, sometimes unfairly
bogging down database performance. JDBC 4 allows an application to associate
metadata with a database connection via the setClientInfo()
method, which consumes a name/string value pair, or a Properties
object. Diagnostic tools can subsequently retrieve the name and characteristics
of applications causing database problems.

Connection to a database requires that a suitable JDBC database driver be
loaded in the client's VM. In the early days of JDBC, it was common to load a
suitable driver via Class.forName(), passing in the name of the
class implementing the JDBC Driver interface. The
DriverManager class later offered a more flexible means of
managing JDBC drivers in a client application. For a driver to become
available, DriverManager's registerDriver() had to be
invoked with the driver's class name. Alternatively, you could specify the
drivers to load via the jdbc.drivers system property. When
DriverManager initializes, it attempts to load the drivers
associated with that property.

JDBC 4 adds the J2SE Service Provider mechanism as another means to specify
database drivers. For this to work, driver JAR files must include the file
META-INF/services/java.sql.driver. That file must contain a single
line with the name of the JDBC driver's implementation of the
Driver interface. Invoking getConnection() on
DriverManager will load a driver so packaged, if needed. Upon
loading the driver, an instance of the driver is created, and then
registerDriver() is invoked to make that driver available to
clients.