Weitere aktuelle Java-Titel finden Sie bei dpunkt.
 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index


18.12

JDBC und Portabilität


Trotz der allgemeinen Definition einer relationalen Datenbankschnittstelle mit JDBC gibt es dennoch einige Punkte, die man bei der Programmierung von JDBC berücksichtigen sollte, wenn man wirklich portablen Code erstellen will, der auch auf anderen Datenbanksystem lauffähig ist: Obwohl die oben genannten Punkte eine geringere Portabilität von JDBC-Anwendungen mit sich bringen, kann man doch durch gutes objektorientiertes Design der Anwendung den Aufwand bei der Portierung auf ein anderes Datenbanksystem in Grenzen halten. Angenommen, es wird eine Anwendung für eine Oracle-Datenbank entwickelt. Dann können die Datenbankzugriffe in zwei Kategorien eingeteilt werden: In Abbildung 18.27 ist ein Klassendiagramm zu sehen, das zeigt, wie man durch diese Unterteilung relative leicht portierbare Anwendungen erstellen kann.

Abbildung 18.27: Entwurfsmuster für portable JDBC-Anwendungen
Abbildung 18.27

Die Klasse GenericBuchshopDatabaseImpl stellt eine allgemeine Implementierung der Datenbankzugriffe zur Verfügung. Wenn sich einige Zugriffe überhaupt nicht allgemein implementieren lassen, bzw. wenn es einen sehr hohen Aufwand erfordert, einige Funktionen allgemein zu implementieren, kann man die Klasse und die entsprechenden Methoden auch als abstract deklarieren und die Implementierung offen lassen, wie es in folgendem Beispiel gemacht wurde:

  package buchshop.server;

  import java.sql.*;

  public abstract class GenericBuchshopDatabaseImpl {
    Connection con;

    public GenericBuchshopDatabaseImpl() {
      // hier Initialisierung der Datenbankverbindung
    }
 
    public Produkte[] getProdukte(String kategorie) {
      // hier Abfrage der Produkte
    }

    public abstract Kategorien[] getKategorien();
  }
Die Methode getKategorien() wurde im Beispiel als abstract deklariert, da es für hierarchische Abfragen keine allgemeingültige Implementierung gibt. Da die aktuelle Implementierung mit Oracle gemacht wird und dort der CONNECT BY-Operator zur Verfügung steht, wird die Implementierung dieser Methode deshalb zunächst offen gelassen. Dadurch wird zunächst unnötige Arbeit vermieden. Später kann diese Methode allerdings einfach ergänzt werden. Von dieser Klasse wird nun eine zweite Klasse OracleBuchshopDatabaseImpl abgeleitet, die die Lücken der Basisklasse füllt, wie in folgendem Listing zu sehen ist:
  package buchshop.server;

  import java.sql.*;

  public class OracleBuchshopDatabaseImpl
                extends  GenericBuchshopDatabaseImpl {

    public OracleBuchshopDatabaseImpl() {
      super();
    }

    public Kategorien[] getKategorien() {
      // hier Abfrage der Kategorien
    }
  }
Hier kann nun die hierarchische Abfrage in der Methode getKategorien() mit Oracle-spezifischem SQL implementiert werden. Für die Verwendung eines anderen Datenbanksystems, das auch hierarchische Abfrage mit anderen Konstrukten erlaubt, muss lediglich eine zweite Klasse von GenericBuchshopDatabaseImpl abgeleitet werden, die diese Methode implementiert. Eine Implementierung mit DB2 kann hierzu z. B. Gebrauch von den dort verfügbaren Common Table Expressions machen. Bei der späteren Benutzung dieser Zugriffsklassen muss man lediglich wissen, welches Datenbanksystem verwendet werden soll:
  GenericBuchshopDatabaseImpl db;
  db = new OracleBuchshopDatabaseImpl();
  Kategorien[] k = db.getKategorien();
Zunächst wird eine Variable vom Typ GenericBuchshopDatabaseImpl definiert. Danach wird ein Exemplar von OracleBuchshopDatabaseImpl erzeugt und dieser Variablen zugewiesen. Das funktioniert deshalb, da die Oracle-Implementierung von der allgemeinen Implementierung abgeleitet wurde und somit auch ein Exemplar der übergeordneten Klasse ist (wenn auch ein spezielles Exemplar). Da die Oracle-Implementierung keine neuen Methoden definiert, sondern nur welche überschreibt, die bereits in der Oberklasse definiert wurden, verfügt die Oberklasse über genau dieselben Methoden wie die Oracle-Implementierung. Dass eine Methode in der Oberklasse abstract definiert wurde, spielt keine Rolle. Wichtig ist nur, dass sie überhaupt definiert wurde. Wenn man nun die Methode getKategorien() aufruft, wird tatsächlich getKategorien() der Oracle-Implementierung aufgerufen, da ein derartiges Exemplar in der Variable gespeichert wurde. Für die Benutzung einer konkreten Datenbank-Implementierung muss man lediglich ein Exemplar der jeweiligen Implementierungsklasse (z. B. DB2BuchshopDatabaseImpl) erzeugen und in der Variablen speichern.


 Inhaltsverzeichnis   Auf Ebene Zurück   Seite Zurück   Seite Vor   Auf Ebene Vor   Eine Ebene höher   Index

Copyright © 2002 dpunkt.Verlag, Heidelberg. Alle Rechte vorbehalten.