Datenbanken mit Java und JDBC

JDBC (Java-Database-Connectivity) ist ein von der Firma Sun entwickeltes Java-Paket, welches über Datenbankobjekte und dazugehörende Methoden den Zugriff auf relationale Datenbanken ermöglicht. Die Grundlage von JDBC ist die Schnittstellenbeschreibung SQL-Call-Level-Interface (CLI) von X/Open. Damit besitzt JDBC die gleiche Basis wie die C-Schnittstelle ODBC der Firma Microsoft. Die API-Spezifikation für JDBC wird im Rahmen des JDK (Java Development Kit) von Sun zu Verfügung gestellt.

Die Datenbankanbindung mit JDBC besitzt einige Vorteile, und zwar:

  • Plattformunabhängigkeit
  • Geringer Aufwand bei der Portierung von Programmen auf andere Datenbanksysteme
  • Einfache Programmierung


Ein wesentlicher Nachteil von JDBC ist leider die vergleichsweise schlechten Performance der Datenbankzugriffe, was allerdings nur bei zeitkritischen Anwendungen ins Gewicht fällt. Durch das Datenbankdesign und entsprechende Server-Hardware kann hier jedoch einiges ausgeglichen werden.

Funktionsweise

JDBC definiert Objekte und Methoden, die es dem Programmierer ermöglichen, in einer Java-Applikation den Zugriff auf relationale Datenbanken zu realisieren. Der Zugriff erfolgt dabei im wesentlichen folgendermassen:
  • Herstellung einer Verbindung zur Datenbank über den entsprechenden JDBC-Treiber für die verwendete Datenbank
  • Erstellung eines Statement-Objektes
  • Weitergabe des auszuführenden Statements über das Statement-Objekt an das Datenbanksystem
  • Abholung der Ergebnisse über die Ergebnisdatensätze
  • Schließen der Verbindung zur Datenbank
Die Java-Applikation läuft dabei typischerweise auf einem Client-Rechner, der eine Verbindung zu einer (oder mehreren) auf einem Remote-Server liegenden Datenbank(en) aufbaut.

Die Datenbankverbindungen, die in Form von Java-Objekten erzeugt werden, werden vom JDBC-Treiber-Manager verwaltet. Dieser kann mehrere Verbindungen zu unterschiedlichen Datenbanken gleichzeitig verwalten und ermöglicht somit auch den Zugriff auf verteilte Datenbanksysteme. Dabei wird Über JDBC ein Objekt der Klasse "java.sql.DriverManager" erzeugt, welche das Laden von Datenbanktreibern durchführt und über die Methode "DriverManager.getConnection()" eine oder mehrere Objekte vom Typ "java.sql.Connection" erzeugt, über die Verbindungen zu verschiedenen Datenbanken hergestellt werden können.

Die JDBC-Datenbank-Treiber lassen sich in vier verschiedene Kategorien (Typ-1, Typ-2, Typ-3, Typ-4) einteilen. Sie unterscheiden sich im wesentlichen darin, dass Typ3 und 4 völlig in Java implementiert sind und bei den Typen 1 und 2 auf native Methoden zurückgegriffen wird.
  • Typ-1: Bei dieser Variante wird für den Zugriff auf die Datenbank ein nativer ODBC-Treiber verwendet, der am Client installiert sein muss und über die "JDBC-ODBC-Bridge" von Sun angesteuert wird.
    Das Java-Programm bindet über den Treiber-Manager den JDBC-ODBC-Bridge-Treiber ein, der seinerseits über eine native Schnittstelle den ODBC-Teiber-Manager in Verbindung mit einem am Client installierten ODBC-Treiber zur Datenbankanbindung anspricht.
  • Typ-2: Hier wird der native ODBC-Treiber durch einen nativen herstellerabhängigen Treiber ersetzt. Auch dieser Treiber muß lokal am Client installiert werden. Das Java-Programm bindet über den Treiber-Manager einen nativen JDBC-Treiber ein, welcher über native API-Schnittstellen die Verbindung zur Datenbank herstellt.
  • Typ-3: Hier greift das Programm auf eine serverseitige Middleware-Installation zu, welche den Zugriff auf die Datenbank realisiert. Dabei ist am Clinnt keine Treiberinstallation notwendig, da der universelle Treiber vom Server geladen werden kann und der "echte" Treiber auf dem Server ausgeführt wird. Das Java-Programm bindet über den Treiber-Manager einen universellen Java-JDBC-Treiber ein, welcher die Aufrufe in ein von der verwendeten Datenbank unabhängiges Protokoll übersetzt und an eine am Server installierte Middleware-Applikation schickt. Diese wandelt die Aufrufe in für die verwendete Datenbank spezifische Aufrufe um, und realisiert so die Datenbankanbindung.
  • Typ-4: Bei dieser Variante werden Treiber in reinem Java-Code verwendet. Die Anbindung von nativem Code entfällt somit. Diese Alternative ist die modernste, da sie durch die fehlende Einbindung von nativem Code die Plattformunabhängigkeit von Java unterstützt und andererseits den Download der Treiber vom Webserver auf den Client ermöglicht. Das Programm bindet über den Treiber-Manager einen nativen, für die verwendete Datenbank spezifischen, JDBC-Treiber ein, welcher auf direktem Wege die Datenbankverbindung herstellt.
Verwendung von JDBC in Java Programmen

Die Implementierung einer Datenbankanbindung verläuft nach dem folgenden Schema:
  • Importieren der benötigten Klassen Die für die Ausführung von JDBC notwendigen Klassen befinden sich alle im Package "java.sql". Diese Klassen müssen vor der Benutzung im Java-Programm importiert werden. Durch den Platzhalter "*", werden alle Klassen des angegebenen Paketes importiert. Die Anweisung für den Import der JDBC-Klassen lautet also:
        import java.sql.*;
    
  • Laden des JDBC-Datenbanktreibers Zur Ausführung von JDBC-Befehlen muß ein Datenbanktreiber geladen sein. Dieser setzt die Anweisungen in eine Form um, welche vom Datenbanksystem verstanden wird. Der Treiber wird mit dem Java "class loader" durch die Methode "class.forName()" geladen. Die Anweisung für das Laden des MySQL-JDBC-Treibers lautet also beispielsweise:
        Class.forName("org.gjt.mm.mysql.Driver"); 
    
  • Verbinden zur Datenbank Die Verbindung zur Datenbank wird durch den JDBC-Driver-Manager durchgeführt. Es handelt sich dabei um eine Klasse aus dem java.sql Package. Hergestellt wird eine Verbindung mit der Methode "getConnection()". Sie erwartet bis zu drei Parameter:
    • String url - Der URL der Datenbank, zu welcher die Verbindung aufgenommen werden soll
    • String user - Der Anmeldename an der Datenbank
    • String password - Das Paßwort für die Datenbankanmeldung
    Dabei sind die beiden letzten Parameter optional und können eventuell auch als Liste übergeben werden. Bei fehlerfreier Ausführung wird eine geöffnete Datenbankverbindung vom Typ "Connection" als Ergebnis zurückgeliefert:
        Connection conn = 
            DriverManager.getConnection(dburl,user,passwd);
    
    Oder eben beispielsweise:
        Connection conn = DriverManager.getConnection(
            "jdbc:mysql://localhost:3306/mydatabase?"+
            "user=dbuser&password=mysecretpw"); 
    
  • Erzeugung eines Statements Ein JDBC-Statement besteht aus einem Objekt der Klasse Statement, welches mit der Methode "createStatement()" der Klasse Connection erzeugt wird. Zu beachten ist, daß diese Methode für eine bereits bestehende Datenbankverbindung erfolgen muß. Die Syntax hierfür lautet also:
        Statement stmt = conn.createStatement();
    
  • Ausführen eines Statements Ein Statement wird mit einer der beiden Methoden "executeQuery" (für Abfragen) oder "executeUpdate()" (bei Update, Insert und Delete) ausgeführt. Die Methode bezieht sich immer auf ein bestehendes Statement und erwartet als Eingabeparameter den String für das auszuführende Statement. Der Rückgabewert ist entweder vom Typ "ResultSet" (Ergebnistabelle bei Abfragen, Auswertung siehe weiter unten) oder "int" (Anzahl der geänderten Datensätze bei Update). Die Syntax lautet daher beispielsweise:
        ResultSet rs = stmt.executeQuery(
            "SELECT DISTINCT datum FROM meinetabelle");
    
    oder eben
        int result = stmt.executeUpdate(
            "INSERT INTO meinetabelle (col1) VALUES (1)");
    
  • Auswerten des Ergebnisses eine Statements Das Ergebnis einer Abfrage ("executeQuery") ist eine Ergebnistabelle vom Typ "ResultSet". Da der Inhalt und der Aufbau dieser Ergebnistabelle von der zugrundeliegenden Datenbanktabelle (auf der die Abfrage ausgeführt wurde) abhängt, ist sie nicht mit einfachen Mitteln auszugeben, sondern muß mit den entsprechenden (vom Interface "ResultSet" zur Verfügung gestellten) Methoden ausgewertet werden. Zum Beispiel kann die Ergebnistabelle der folgenden Abfrage SELECT nummer, bezeichnung FROM BESTELLUNGEN; welche einen numerischen Wert, die Bestellnummer, und einen String (die Bezeichnung) liefert, mit den folgenden Methoden ausgewertet werden:
        int bestellnr = rs.getInt("nummer");
        String bezeichnung = rs.getString("bezeichnung");
        
        // auch Scheifen sind moeglich
    
        while (rs.next()) {
          String bez  = rs.getString(1);
          System.out.println(bez + " ");
        }
    
    Das Interface "ResultSet" bietet für jeden Datentyp eine passende Methode der Art "getTyp()" an, mit der die entsprechenden Spalten des Ergebnisses ausgelesen werden können. Ist der Aufbau der zugrundeliegenden Datenbanktabelle nicht bekannt (Zum Beispiel bei "SELECT * FROM BESTELLUNGEN"), muß erst über die Methode "Connection.GetMetaData()" für eine bestehende Verbindung die Struktur der Datenbank (der Tabelle) ausgelesen und mit den entsprechenden Methoden ausgewertet werden.
  • Schließen der Datenbankverbindung Für das Abmelden von der Datenbank (also dem Schließen der Verbindung) wird die Methode "close()" der Klasse "Connection" verwendet, die für eine bestehende Verbindung und ohne Parameter aufgerufen wird:
        conn.close();
    
Ein Beispiel

import java.sql.*;

public class Connect {
  
  public static void main(String[] Args) {
    
    try { 

      Class.forName("org.gjt.mm.mysql.Driver"); 
      Connection conn = null;
      conn = DriverManager.getConnection(
      "jdbc:mysql://localhost:3306/mydatabase?"+
      "user=dbuser&password=mysecretpw"); 
      Statement stmt = conn.createStatement();
      
      ResultSet rs = 
      stmt.executeQuery("SELECT DISTINCT datum FROM table");
      // ODER Z.B.
      // .executeUpdate("INSERT INTO table (col1) VALUES (1)");
      
      while (rs.next()) {
        String b  = rs.getString(1);
        System.out.println(b + "   ");
      }

    } catch (Exception E) { 
        System.out.println("ERROR: " + E.getMessage()); 
    }
  }
}

Alle Touren

Schneebergwege

Raxsteige

Geführte Touren

Perl

Literatur

Musik