Advanced Java Services | Treiber laden |
Die Klasse DriverManager hat ausschließlich statische Methoden. Mir ihr ist es u.a. möglich, sich eine Liste der geladenen Treiber ausgeben zu lassen. Auch der Verbindungsaufbau zur Datenbank kann über die Klasse DriverManager erfolgen. Mehr darüber auf der Seite Verbindungsaufbau.
Ab der Version 1.6 ist ein explizites Laden eines Datenbanktreibers nicht mehr notwendig.
Ruft man die folgende kleine Methode aus main() heraus auf, so stellt man fest, daß bereits der ODBC-Treiber von Sun
geladen wurde (sun.jdbc.odbc.JdbcOdbcDriver).
public static void printAllDrivers() { int j=0 ; for( Enumeration en = DriverManager.getDrivers() ; en.hasMoreElements() ; j++) System.out.println( en.nextElement().getClass().getName() ); if (j==0) System.out.println("Treiberliste leer"); System.out.println("-----------------------------------------------"); }
Dieser Treiber wird von der JRE also automatisch bei jedem Programmstart geladen.
Des weiteren erkennt die JRE auch externe Treiber die in jar-Dateien gepackt ins ext-Verzeichnis kopiert werden und lädt sie automatisch bei jedem Programmstart. Kopiert man etwa den MySQL-Treiber (mysql-connector-java-5.1.12-bin.jar) in das ext-Verzeichnis so liefert die obige Methode folgendes Ergebnis:
sun.jdbc.odbc.JdbcOdbcDriver com.mysql.jdbc.Driver
Die folgenden Erläuterungen sind mit der Version 1.6 nur noch aus historischen Gründen interessant.
Zur Laufzeit einer Java-Applikation hält der ByteCodeInterpreter zu jeder verwendeten Klasse eine Klasse vom Typ Class. Diese enthält Informationen über die entsprechende Javaklasse, die zur Laufzeit benötigt werden. Das zu einer Klasse gehörende Objekt vom Typ Class wird normalerweise automatisch geladen, wenn es gebraucht wird. Gebraucht wird es z.Bsp. immer dann, wenn ein Objekt eines bestimmten Typs angelegt wird. Aber auch für den Aufruf einer statischen Methode oder für den Zugriff auf statische Daten wird das zugehörige Class-Objekt gebraucht. Eine sehr nützliche und häufige Anwendung der Klasse Class besteht darin, sich den genauen Typ eines Objektes ausgeben zu lassen.
Object obj = arrayList.get(i) ; System.out.println("The class type of " + obj + " is " + obj.getClass().getName());
Für das Laden eines Datenbanktreibers reicht es, das zur Treiberklasse gehörende Class-Objekt anzulegen. Man braucht also nicht (unbedingt) ein Objekt der Treiberklasse. Im folgenden werden zwei Methoden zum Anlegen des zu einer Treiberklasse gehörenden Class-Objektes beschrieben.
Eine Möglichkeit zum Laden der Treiber ist die Verwendung der statische Methode Class.forName(). Wird der Treiber nicht gefunden, so wirft die Methode eine ClassNotFoundException.
Mit der statischen Methode DriverManager.getDrivers() können alle geladenen Treiber ausgegeben werden.
In den letzten beiden Fällen werden die Treiber nicht von Sun bereitgestellt, sondern müssen vom entsprechenden Datenmbankanbieter heruntergeladen werden. Die Treiber stehen dann jeweils in eigenen packages in einem .jar-File. Wo man diese Treiber erhält ist auf der vorigen Seite beschrieben worden.
Zu jeder Klasse (und jedem Interface und jedem Array und jedem primitiven Datentyp) gibt es eine beim
compilieren automatische erzeugte statische Konstante, die den Namen <name-der-klasse>.class trägt
und vom Typ Class ist.
Mit ihr ist es noch einfacher, einen Treiber zu laden. Diese Variante war in der Version 1.5 nicht mehr
anwendbar. Das Anlegen eines class-Literals führte in der Version 1.5 nicht mehr dazu, daß der statische
Initialisierer abgearbeitet wird. In der Version 1.6 ist dies aber wieder möglich.
Diese Methode ist deswegen elegant, da schon zur Compilezeit festgestellt wird ob die Klasse existiert.
Dagegen ist bei dem Aufruf Class.forName("....") eine Exceptionbehamdlung notwendig, da zur Laufzeit eine
ClassNotFoundException geworfen wird, falls die Klasse nicht gefunden wird.
Das folgende Codebeispiel lädt Treiber mit Hilfe des Literals class und gibt eine Liste der
verfügbaren Treiber aus.
import java.util.Enumeration; import java.sql. DriverManager; public class TreiberLaden1 { public static void main(String[] args) { //Treiber laden für ODBC Class drv1 = sun.jdbc.odbc.JdbcOdbcDriver.class; //Treiber laden für MySQL Class drv2 = com.mysql.jdbc.Driver.class; //Treiber laden für oracle Class drv3 = oracle.jdbc.driver.OracleDriver.class; System.out.println("Liste der verfuegbaren Treiber"); System.out.println("------------------------------"); Enumeration drivers = DriverManager.getDrivers() ; while(drivers.hasMoreElements() ) System.out.println(drivers.nextElement().getClass().getName() ); } }
Wird ein Treiber nicht gefunden, so meldet sich der bereits der Compiler, zum Beispiel mit:
package com.mysql.jdbc does not exist Class drv3 = oracle.jdbc.driver.OracleDriver.class;
In dieser Variante erzeugt man ein Objekt vom Typ Driver mit einem Konstruktoraufruf.
Driver drv = new sun.jdbc.odbc.JdbcOdbcDriver();
Damit wird der Treiber geladen, also beim DriverManager registriert.
Die auf der nächsten Seite folgende Graphik zeigt die verschiedenen Implementierungen des Interfaces java.sql.Driver