[Top] [Prev] [Next]

## DriverManager

NOTE: The material in this chapter is based on JDBCtm API Tutorial and Reference, Second Edition: Universal Data Access for the Javatm 2 Platform, published by Addison Wesley as part of the Java series, ISBN 0-201-43328-1.

### 3.1 DriverManager Overview

The `DriverManager` class is the traditional management layer of JDBC, working between the user and the drivers. It keeps track of the drivers that are available and handles establishing a connection between a database and the appropriate driver. In addition, the `DriverManager` class attends to things like driver login time limits and the printing of log and tracing messages.

Note that the `javax.sql` package, otherwise known as the JDBC 2.0 Standard Extension API, provides the `DataSource` interface as an alternate and preferred means of connecting to a data source. However, the `DriverManager` facility can still be used with drivers that support `DataSource` implementations.

For simple applications, the only method in the `DriverManager` class that a general programmer needs to use directly is `DriverManager.getConnection`. As its name implies, this method establishes a connection to a database. An application may call the `DriverManager` methods `getDriver`, `getDrivers`, and `registerDriver` as well as the `Driver` method `connect`, but in most cases it is better to let the `DriverManager` class manage the details of establishing a connection.

#### 3.1.1 Keeping Track of Available Drivers

The `DriverManager` class maintains a list of `Driver` classes that have registered themselves by calling the method `DriverManager.registerDriver`. All `Driver` classes should be written with a static section (a static initializer) that creates an instance of the class and then registers it with the `DriverManager` class when it is loaded. Thus, a user would not normally call `DriverManager.registerDriver` directly; it should be called automatically by a `Driver` class when it is loaded. A `Driver` class is loaded, and therefore automatically registered with the `DriverManager`, in one of two ways:

1. by calling the method `Class.forName`. This explicitly loads the driver class. Since it does not depend on any external setup, this way of loading a driver is the recommended one for using the `DriverManager` framework. The following code loads the class `acme.db.Driver`:

   >     Class.forName("acme.db.Driver");

   If `acme.db.Driver` has been written so that loading it causes an instance to be created and also calls `DriverManager.registerDriver` with that instance as the parameter (as it should do), then it is in the `DriverManager`'s list of drivers and available for creating a connection.

2. by adding the `Driver` class to the `java.lang.System` property `jdbc.drivers`. This is a list of driver classnames, separated by colons, that the `DriverManager` class loads. When the `DriverManager` class is initialized, it looks for the system property "`jdbc.drivers`," and if the user has entered one or more drivers, the `DriverManager` class attempts to load them. The following code illustrates how a programmer might enter three driver classes in ~/.hotjava/properties (HotJava loads these into the system properties list on startup):

>     jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.test.ourDriver

> The first call to a `DriverManager` method will automatically cause these driver classes to be loaded.

Note that this second way of loading drivers requires a preset environment that is persistent. If there is any doubt about that being the case, it is safer to call the method `Class.forName` to explicitly load each driver. This is also the right method to use to bring in a particular driver since once the `DriverManager` class has been initialized, it will never recheck the `jdbc.drivers` property list.

In both of these cases, it is the responsibility of the newly-loaded `Driver` class to register itself by calling `DriverManager.registerDriver`. As mentioned, this should be done automatically when the class is loaded.

For security reasons, the JDBC management layer will keep track of which class loader provided which driver. Then when the `DriverManager` class is opening a connection, it will use only drivers that come from the local file system or from the same class loader as the code issuing the request for a connection.

#### 3.1.2 Establishing a Connection

Once the `Driver` classes have been loaded and registered with the `DriverManager` class, they are available for establishing a connection with a database. When a request for a connection is made with a call to the `DriverManager.getConnection` method, the `DriverManager` tests each driver in turn to see if it can establish a connection.

It may sometimes be the case that more than one JDBC driver is capable of connecting to a given URL. For example, when connecting to a given remote database, it might be possible to use a JDBC-ODBC bridge driver, a JDBC-to-generic-network-protocol driver, or a driver supplied by the database vendor. In such cases, the order in which the drivers are tested is significant because the `DriverManager` will use the first driver it finds that can successfully connect to the given URL.

First the `DriverManager` tries to use each driver in the order it was registered. (The drivers listed in `jdbc.drivers` are always registered first.) It will skip any drivers that are untrusted code unless they have been loaded from the same source as the code that is trying to open the connection.

It tests the drivers by calling the method `Driver.connect` on each one in turn, passing them the URL that the user originally passed to the method `DriverManager.getConnection`. The first driver that recognizes the URL makes the connection.

At first glance this may seem inefficient, but it requires only a few procedure calls and string comparisons per connection since it is unlikely that dozens of drivers will be loaded concurrently.

The following code is an example of all that is normally needed to set up a connection with a driver such as a JDBC-ODBC bridge driver.

>     Class.forName("jdbc.odbc.JdbcOdbcDriver"); //loads the driver
>     String url = "jdbc:odbc:fred";
>     Connection con = DriverManager.getConnection(
>     		url, "userID", "passwd");

The variable con represents a connection to the data source "fred" that can be used to create and execute SQL statements.

With the addition of the JDBC 2.0 Standard Extension API, a `DataSource` object can be used to establish a connection with a data source. The `DriverManager` can still be used, but a `DataSource` object offers several advantages over the `DriverManager` and is the preferred alternative. Developers who are writing Enterprise JavaBeans components, however, should always use a `DataSource` object instead of the `DriverManager`. Using a properly implemented `DataSource` object is the only way to get connections that are pooled and that can participate in distributed transactions.

#### 3.1.3 DriverManager Methods Are Static

All `DriverManager` methods are declared `static`, which means that they operate on the class as a whole and not on particular instances. In fact, the constructor for `DriverManager` is declared `private` to prevent users from instantiating it. Logically, there is one instance of the `DriverManager` class. This means that methods are called by qualifying them with `DriverManager`, as in the following line of code.

>     DriverManager.setLogWriter(out);

[Top] [Prev] [Next]

Copyright © 1999, Sun Microsystems, Inc. All rights reserved.