This article is sponsored by the Java Community Process.
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). 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.
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
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
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
method, which consumes a name/string value pair, or a
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
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
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
This article is sponsored by the Java Community Process.