Delicious

Class.forName() and DriverManager.getConnection()

Do you know how the following code works?

Class.forName("some.database.Driver");
Connection conn = DriverManager.getConnection("connection_url", "username", "password");

A half-backed answer would be Class.forName() loads the database driver class some.database.Driver, and DriverManager.getConnection() returns the appropriate Connection instance based on the 'connection_url' provided.

Let's figure out what is actually happening.

The Class.forName() method is responsible of loading the class some.database.Driver. There is a static block within all Database Driver implementations which would look something like this:

static {
  try{
    java.sql.DriverManager.registerDriver( new Driver() );
  } catch(SQLException e) { throw new RuntimeException("Can't register driver!") }
}

The Driver class tries to register it's own instance with the DriverManager.

Now when we call DriverManager.getConnection(), it iterates through all the drivers registered with it and checks the appropriate driver for the 'connection_url'. If you examine the code in the class you would find a method getDriver():

public static Driver getDriver(String url) throws SQLException {
  Enumeration e = drivers.elements();
  while(e.hasMoreElements()) {
    Driver d = (Driver)e.nextElement();
    if ( d.acceptsURL(url) ) return d;
  }
  throw new SQLException("No driver found for " + url);
}

As you might have observed, the acceptsURL() method is called for each registered drivers and the first driver that believes it could connect to the specified database is returned.


Delicious