Software- und Organisations-Service GmbH JAVA-KLASSEN SOSConnection Zugriffsschicht für Datenbanken Klassendokumentation 14. August 2007 Software- und Organisations-Service GmbH · Giesebrechtstr. 15 · D-10629 Berlin · Telefon (030) 86 47 90-0 · Telefax (030) 8 61 33 35 Connection - Zugriffsschicht für Datenbanken 2 Inhaltsverzeichnis 1 Zielsetzung.................................................................................................................................................5 2 Datenbankabstraktion...............................................................................................................................5 2.1 Performance.....................................................................................................................................5 2.2 Funktionalität...................................................................................................................................5 2.3 Kompatibilität ..................................................................................................................................6 2.4 Schlussfolgerung für die Abstraktion ...........................................................................................6 3 Unterstützte Datenbanksysteme..............................................................................................................7 4 Klassenhierarchie und Deployment ........................................................................................................7 5 Methoden....................................................................................................................................................7 5.1 Standardisierte Aufrufe...................................................................................................................7 5.1.1 createInstance()............................................................................................................................7 5.1.2 connect() .......................................................................................................................................7 5.1.3 disconnect() ..................................................................................................................................8 5.1.4 execute()........................................................................................................................................8 5.1.5 executeUpdate() ...........................................................................................................................8 5.1.6 executeQuery() .............................................................................................................................8 5.1.7 closeQuery() .................................................................................................................................8 5.1.8 get()................................................................................................................................................8 5.1.9 getResultSet() ...............................................................................................................................9 5.1.10 getSingle().....................................................................................................................................9 5.1.11 getSingleAsProperties() ..............................................................................................................9 5.1.12 getSingleValue() ...........................................................................................................................9 5.1.13 getArray() ....................................................................................................................................10 5.1.14 getArrayAsProperties() ..............................................................................................................10 5.1.15 getArrayAsVector().....................................................................................................................10 5.1.16 getArrayValue()...........................................................................................................................10 5.1.17 updateBlob() ...............................................................................................................................10 5.1.18 updateBlob() ...............................................................................................................................10 5.1.19 getBlob() .....................................................................................................................................11 5.1.20 getBlob() .....................................................................................................................................11 5.1.21 updateClob() ...............................................................................................................................11 5.1.22 updateClob() ...............................................................................................................................11 5.1.23 getClob() .....................................................................................................................................11 5.1.24 getClob() .....................................................................................................................................11 5.1.25 getLastSequenceValue() ...........................................................................................................12 5.1.26 getStatements() ..........................................................................................................................12 5.1.27 commit() ......................................................................................................................................12 5.1.28 rollback () ....................................................................................................................................12 6 SQL-Funktionen.......................................................................................................................................12 6.1 %lower( String string ) ..................................................................................................................12 6.2 %upper( String string ) .................................................................................................................13 6.3 %now()............................................................................................................................................13 6.4 %timestamp( String timestamp ) .................................................................................................13 6.5 %timestamp_iso( String iso_timestamp ) ...................................................................................13 6.6 %cast( String expression ) ...........................................................................................................13 6.7 %updlock() .....................................................................................................................................13 7 Tracing......................................................................................................................................................13 8 Profiling ....................................................................................................................................................13 9 Konfigurationsdatei.................................................................................................................................14 Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 3 10 Besonderheiten beim Verbindungsaufbau ...........................................................................................14 10.1 MSSQL............................................................................................................................................14 10.2 MySQL ............................................................................................................................................15 10.3 Oracle .............................................................................................................................................15 10.4 DB2 .................................................................................................................................................15 10.5 Firebird ...........................................................................................................................................15 10.6 PostgreSQL....................................................................................................................................15 11 Wie werden weitere Datenbanken angeschlossen? ............................................................................15 11.1 Implementierung der Konstruktoren ...........................................................................................15 11.1.1 public SOSMyDatabaseConnection().......................................................................................16 11.1.2 public SOSMyDatabaseConnection(Connection connection, SOSLogger logger).............16 11.1.3 public SOSMyDatabaseConnection(Connection connection) ..............................................16 11.1.4 public SOSMyDatabaseConnection(String configFileName, SOSLogger logger) ..............16 11.1.5 public SOSMyDatabaseConnection(String configFileName) ................................................16 11.1.6 public SOSMyDatabaseConnection(String driver, String url, String dbuser, String dbpassword, SOSLogger logger) ..........................................................................................................16 11.1.7 public SOSMyDatabaseConnection(String driver, String url, String dbuser, String dbpassword) ............................................................................................................................................16 11.2 Implementierung abstrakter Methoden der Basisklasse...........................................................16 11.2.1 public void connect() .................................................................................................................16 11.2.2 public void prepare(Connection connection) .........................................................................16 11.2.3 protected boolean prepareGetStatements(StringBuffer contentSB, StringBuffer splitSB, StringBuffer endSB) ................................................................................................................................16 11.2.4 public String getLastSequenceQuery(String sequence) .......................................................16 11.2.5 public String[] getReplacement()..............................................................................................16 11.2.6 rotected String replaceCasts(String expression) ...................................................................17 11.2.7 public String toDate(String dateString) ...................................................................................17 11.3 Implementierung optionaler Methoden.......................................................................................17 11.3.1 protected GregorianCalendar getDateTime(String format) ...................................................17 11.3.2 public Vector getOutput()..........................................................................................................17 11.3.3 public int parseMajorVersion(String productVersion) ...........................................................17 11.3.4 public int parseMinorVersion(String productVersion) ...........................................................17 Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 4 Kontakt Software- und Organisations-Service GmbH Giesebrechtstr. 15 10629 Berlin Germany Telephon +49 30 86 47 90-0 Telefax +49 30 8 61 33 35 Mail [email protected] Web www.sos-berlin.com Letze Änderung: 14. August 2007 Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 1 5 Zielsetzung Die Klassen des Pakets SOSConnection implementieren ein einheitliches Interface für den Zugriff auf unterschiedliche Datenbanksysteme. Durch Verwendung dieser Klassen ist es möglich, Java-Anwendungen für den parallelen Einsatz mit mehreren Datenbanksystemen zu entwickeln. Die Klassen stellen eine Abstraktionsschicht dar, ohne zwanghaft Einschränkungen in der Entwicklung von Anwendungen aufzuerlegen. Als ergänzende Beschreibung steht die API-Dokumentation im JavaDoc-Format zur Verfügung. 2 Datenbankabstraktion Es ist grundsätzlich nicht Ziel einer Abstraktionsschicht unterschiedliche Zugriffsdialekte für Datenbanken auf kleinstem gemeinsamem Nenner zu nivellieren: jede Datenbank hat individuelle Stärken, ein Verzicht auf diese "features" wäre schlicht kontraproduktiv. Entscheidend für die Anwendung ist es eine klare Priorität zwischen der Orientierung an Performance, Funktionalität und Kompatibilität zu finden. 2.1 Performance Datenbanksysteme beherrschen unterschiedliche "features" zur Performance-Optimierung. Ein Beispiel hierfür ist die LIMIT-Klausel von MySQL: select * from sample_table limit 200 durch Verwendung der Klausel kann die Anzahl zurückzuliefernder Datensätze einer Abfrage im vornherein eingeschränkt werden. Die Klausel wirkt nicht erst beim Abholen von Datensätzen aus einer Ergebnismenge, sondern wird bereits in der Datenbankengine zur Optimierung der Suchstrategie verwendet und die Suche bereits abgebrochen wenn die Trefferzahl erreicht ist. Wenn in Web-Seiten beschränkte Ergebnismengen angezeigt werden sollen, ist diese Klausel sinnvoll einzusetzen, selbst wenn sie nicht kompatibel zum SQLStandard ist: der Geschwindigkeitsvorteil rechtfertigt den Aufwand diese Klausel bedingt in einer Anwendung zu programmieren. Ein analoges Konstrukt für Oracle ist die Klausel: select * from ( select * from sample_table ) where rownum <= 200 die im Ergebnis zwar ebenfalls eine Einschränkung der Ergebnismenge bewirkt, die aber erst beim Auslesen der vollständigen Ergebnismenge der inneren Abfrage durch die äußere Abfrage erfolgt. Wenn eine solche Abfrage aufgrund der Suchbedingungen eine gesamte Tabelle durchliest (full table scan), dann wird deutlich, dass das professionellere Datenbanksystem nicht in jeder Situation das schnellere sein muß. 2.2 Funktionalität Manche Funktionen sind bei Datenbankherstellern schlichtweg aufgrund von Designentscheidungen entfallen obwohl sie sehr nützlich in der Anwendungsentwicklung sind: Als Beispiel sei die MySQL-Funktion affectedRows() genannt, die es erlaubt auch nach ändernden SQLStatements wie UPDATE und DELETE die Anzahl der betroffenen Sätze festzustellen. Eine Anwendung die gezielt nur einen Datensatz ändern will, kann mit dieser Funktion feststellen, ob dies zutrifft. SQL ist aufgrund seiner mengentheoretischen Herkunft nicht in der Lage diese Information in einem SQL-Statement zu liefern. Als Ersatzkonstrukt wird oft darauf verwiesen das Statement select count(*) zu verwenden. Diese führt allerdings zu einer Vergrößerung der Zugriffszeiten, da dieselbe Abfrage ein zweites Mal ausgeführt wird. Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 6 2.3 Kompatibilität Weder Oracle noch MySQL sind 100%ig kompatibel zu einem SQL-Standard. Standards wie SQL92 und SQL99 sind von beiden Datenbanken nicht vollständig implementiert. Als Beispiel sei auf Left Outer JoinAbfragen verwiesen, die Oracle erst ab Version 9.2 standardkonform unterstützt. Eine solche Join-Abfrage liefert zu einer Menge von Sätzen aus zwei Tabellen auch dann ein Ergebnis, wenn in der rechten Tabelle kein entsprechender Treffersatz gefunden wird. Die Oracle-Syntax hierfür lautet: select * from left_table lt, right_table rt where lt.key=rt.key(+) Die SQL99 standardkonforme Syntax lautet: select * from left_table lt left outer join right_table rt on lt.key=rt.key Dieser Zugriff ist daher ohne Rücksicht auf das eingesetzte Datenbanksystem nicht implementierbar. 2.4 Schlussfolgerung für die Abstraktion Von den vorstehenden Beispielen ausgehend könnte man meinen eine Abstraktion vom konkreten Datenbanksystem sei nicht erreichbar. Dies ist zutreffend solange der Begriff Abstraktion fordert, Datenbanken müssten hinsichtlich Ihrer Syntax gleich sein. Fordert man dagegen, dass sie sich gleich verhalten gegenüber einer Anwendung, dann lässt sich dieses Verhalten durch Implementierung einer Zugriffsschicht herstellen. Die SOSConnection-Klassen stellen entsprechend keine Einschränkung dar hinsichtlich der Frage, welche Syntax für SQL-Statements verwendet wird, sondern standardisieren - welche Methoden verfügbar sind, wie sie parametrisiert werden und welche Rückgaben sie liefern - in welchen Formaten Daten zurückgeliefert werden (scalare Typen, arrays) - in welchen Formaten SQL-Funktionen wie upper(), lower() angesprochen werden - wie Zeitstempel an die Datenbank übergeben werden - wie das Fehlermanagement implementiert ist - wie das Tracing von Datenbankaufrufen erfolgt - wie eine vergleichende Messung der Zugriffszeiten (profiling) betrieben werden kann. Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 3 7 Unterstützte Datenbanksysteme Für folgende Datenbanksysteme sind SOSConnection-Klassen verfügbar: Oracle ab Version 8.1.7, incl. 9.2, 10.x MySQL ab Version 3.25, Transaktionsunterstützung ab Version 4.01 MS SQL-Server ab Version 7, incl. 2000, 2005 DB2 ab Version 8 Firebird ab Version 1.5 ODBC-Datenbanken 4 Klassenhierarchie und Deployment Die Basisklasse SOSConnection stellt Zugriffsmethoden zur Verfügung, von dieser Klasse werden weitere DBMS-spezifische Klassen abgeleitet, z.B. SOSOracleConnection, SOSMySQLConnection etc. - Methodenimplementierungen der Basisklasse SOSConnection werden per Vererbung genutzt - Abstrakte Methoden der Basisklasse müssen von abgeleiteten Klassen implementiert werden Alle Klassen werden unter dem Paketnamen sos.connection vorgehalten und mit dem Archiv sos.connection.jar ausgeliefert. Das Paket wird für den Betrieb mit JRE 1.4.2_05 und höher bereitgestellt. 5 Methoden 5.1 Standardisierte Aufrufe Die Methoden aller SOSConnection-Klassen sind in gleicher Weise parametrisiert und liefern dieselben Funktionsergebnisse. Die vollständige Auflistung und die Beschreibung der Parameter kann der API-Dokumentation im JavaDoc-Format entnommen werden. 5.1.1 createInstance() SOSConnection createInstance(String class, String driver, String url, String dbUser, String dbPassword) SOSConnection createInstance(String configFileName) sowie weitere createInstance() Methoden mit ähnlicher Signatur. Die Methode liefert das Objekt einer DBMS-spezifischen SOSConnection-Klasse zurück. Die Verbindung wird aus den Einstellungen einer Konfigurationsdatei oder aus den Methodenargumenten hergestellt, siehe Kapitel "Konfigurationsdatei" für Details bzgl. der erforderlichen Einträge in einer Konfigurationsdatei. 5.1.2 connect() void connect () Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 8 Die Methode besorgt den Verbindungsaufbau zur Datenbank. Anmerkungen Nach dem Verbindungsaufbau werden automatisch folgende Voreinstellungen vorgenommen: Datumsformate: ISO (yyyy-mm-dd hh24:mm:ss) Zahlenformate: . (Punkt) als Dezimalzeichen Transaktionen: automatischer Transaktionsbeginn, kein automatisches Transaktionsende (auto commit=false), nach dem Verbindungsaufbau werden Transaktionen von der Applikation gehandhabt. 5.1.3 disconnect() void disconnect () Die Methode baut die Verbindung zur Datenbank ab. 5.1.4 execute() void execute ( String statement ) Die Methode führt ein Statement aus, z.B. den Aufruf einer Stored Procedure. Diese Methode soll nicht für DML Statements verwendet werden, siehe executeUpdate(), und nicht für Abfragen, für die eine Ergebnismenge vorgehalten werden muss, siehe executeQuery(). 5.1.5 executeUpdate() int executeUpdate ( String query ) Die Methode führt ein DML Statement aus wie UPDATE, INSERT, DELETE. Rückgabewert Die Anzahl betroffener Sätze. 5.1.6 executeQuery() void executeQuery ( String query ) Die Methode führt eine Abfrage aus und erhält die Ergebnismenge. Die Methode kann mit nachfolgenden Aufrufen der get() Methode kombiniert werden, um nacheinander Sätze einer Ergebnismenge zu lesen. 5.1.7 closeQuery() void closeQuery () Die Methode schließt eine Ergebnismenge, die durch einen vorherigen Aufruf der executeQuery() Methode erzeugt wurde. Bitte beachten Sie, dass für den Betrieb mit einem Connection Pool, z.B. mit einem Application Server oder Servlet Container, für jede Verbindung, die an den Connection Pool zurückgegeben wird, alle offenen Ergebnismengen und Transaktionen geschlossen sein müssen. 5.1.8 get() HashMap get () Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 9 Die Methode liest den nächsten Satz der Ergebnismenge einer Abfrage Rückgabewert HashMap bestehend aus Feldnamen und Werten des nächsten Datensatzes. Die Methode wird üblicherweise mit einem while() Konstrukt zum schrittweisen Lesen der Ergebnismenge eingesetzt. Anmerkung Die Feldnamen werden per Voreinstellung in Kleinbuchstaben geliefert; die Schreibweise der Feldnamen kann jedoch mit den Methoden setKeysToUpperCase() und setKeysToLowerCase() geändert werden. 5.1.9 getResultSet() ResultSet getResultSet () Die Methode liefert das Objekt der Ergebnismenge, die durch einen vorherigen Aufruf der Methode executeQuery() erzeugt wurde. Rückgabewert Objekt der Ergebnismenge einer vorherigen Abfrage oder null. 5.1.10 getSingle() HashMap getSingle ( String query ) Die Methode liest einen Datensatz der Ergebnismenge einer Abfrage Rückgabewert HashMap bestehend aus Feldnamen und Werten des ersten Datensatzes, leere HashMap bei leerer Ergebnismenge. 5.1.11 getSingleAsProperties() Properties getSingle ( String query ) Die Methode liest den ersten Satz der Ergebnismenge einer Abfrage. Rückgabewert Properties Collection bestehend aus Feldnamen und Werten des ersten Satzes oder leere Collection bei leerer Ergebnismenge. 5.1.12 getSingleValue() String getSingleValue ( String query ) Die Methode liest einen skalaren Wert, i.d.R. ein Feld, des ersten Satzes der Ergebnismenge einer Abfrage Rückgabewert String oder leerer String im Fall einer leerer Ergebnismenge Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 10 5.1.13 getArray() ArrayList getArray ( String query ) Liefert alle Treffer der Abfrage als ArrayList aus HashMaps zurück. Rückgabewert ArrayList von HashMaps oder leere ArrayList im Fall einer leeren Ergebnismenge. 5.1.14 getArrayAsProperties() Properties getArrayAsProperties ( String query ) Liefert alle Treffer der Abfrage als Collection von Properties zurück. Rückgabewert Eine Properties Collection oder eine leere Collection im Fall einer leeren Ergebnismenge. 5.1.15 getArrayAsVector() Vector getArrayAsVectory ( String query ) Liefert aller Treffer der Abfrage als Vector von HashMaps zurück. Rückgabewert Ein Vector von HashMaps oder ein leerer Vector im Fall einer leeren Ergebnismenge. 5.1.16 getArrayValue() ArrayList getArrayValue ( String query ) Liefert alle Treffer als ArrayList-Objekt zurück. Die Abfrage darf nur ein Feld aus jeweils einem Satz lesen. Rückgabewert ArrayList der Treffer oder leere ArrayList im Fall einer leeren Ergebnismenge. 5.1.17 updateBlob() long updateBlob( String tableName, String columnName, String fileName, String condition ) Die Methode speichert den Inhalt einer Datei in ein Datenbankfeld vom Typ BLOB. Rückgabewert Anzahl gespeicherter Byte 5.1.18 updateBlob() long updateBlob ( String tableName, String columnName, byte[] data, String condition ) Die Methode aktualisiert den Inhalt eines Byte Arrays in einem BLOB-Feld. Rückgabewert Anzahl gespeicherter Byte Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 11 5.1.19 getBlob() byte[] getBlob ( String query ) Die Methode liefert den Inhalt eines BLOB-Felds. Rückgabewert Der Inhalt des BLOB-Felds als Byte Array. 5.1.20 getBlob() long getBlob ( String query, String filename ) Die Methode speichert den Inhalt eines Datenbankfelds vom Typ BLOB in einer neuen Datei. Rückgabewert Anzahl geschriebener Bytes. 5.1.21 updateClob() long updateClob( String tableName, String columnName, String fileName, String condition ) Die Methode speichert den Inhalt einer Datei einem CLOB-Feld. Rückgabewert Anzahl gespeicherter Bytes. 5.1.22 updateClob() long updateClob ( String tableName, String columnName, byte[] data, String condition ) Der Inhalt eines Byte Arrays wird in einem CLOB-Feld aktualisiert. Rückgabewert Anzahl gespeicherter Bytes. 5.1.23 getClob() String getClob ( String query ) Die Methode liefert den Inhalt eines CLOB-Felds. Rückgabewert Inhalt des CLOB-Felds als String. 5.1.24 getClob() long getClob ( String query, String filename ) Die Methode schreibt den Inhalt eines CLOB-Felds in eine Datei. Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 12 Rückgabewert Anzahl geschriebener Bytes. 5.1.25 getLastSequenceValue() String getLastSequenceValue ( String sequence ) Die Methode liefert den letzten Wert eines Sequenzgenerators. Für MySQL ist dies der Wert der Funktion LAST_INSERT_ID(). Für Oracle wird der Name der Sequence angegeben, bei Datenbanken ohne benannte Sequences sollte dieses Argument null sein. Rückgabewert Der letzte Wert eines Sequenzgenerators. 5.1.26 getStatements() ArrayList getStatements ( String statements ) Die Methode liefert einzelne Statements aus einer Reihe von Statements, die als Argument übergeben werden. Die Methode implementiert einen Parser der Statements isoliert und DDL Statements (create procedure etc.) und DML Statements berücksichtigt. Rückgabewert ArrayList isolierter Statements. 5.1.27 commit() void commit () Schließt eine Transaktion ab Anmerkungen Der Aufruf wird bei Einsatz der Klasse SOSHistory ignoriert, der Transaktionsabschluss stattdessen in der Historie gespeichert und zu einem späteren Zeitpunkt ausgeführt. 5.1.28 rollback () void rollback () Rollt eine Transaktion zurück 6 SQL-Funktionen Die nachfolgenden Pseudo-Funktionen werden automatisch auf die Syntax der unterstützten Datenbanksysteme abgebildet. Funktionsnamen werden zur Unterscheidung von SQL-Funktionen durch % präfiziert. 6.1 %lower( String string ) Liefert die SQL-Funktion für die Darstellung des Parameters in Kleinbuchstaben. Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 13 6.2 %upper( String string ) Liefert die SQL-Funktion für die Darstellung des Parameters in Großbuchstaben. 6.3 %now() Liefert den SQL-Code für den aktuellen Zeitstempel, z.B. SYSDATE für Oracle. 6.4 %timestamp( String timestamp ) Konvertiert den Inhalt des übergebenen Zeitstempels aus dem Format dd.mm.yyyy hh24:mm:ss im ISOFormat yyyy-mm-dd hh24:mm:ss und liefert den SQL Code für die Darstellung. Für Oracle könnte dies sein TO_DATE('2007-07-31 12:44:22', 'yyyy-mm-dd HH24:MI:SS'). 6.5 %timestamp_iso( String iso_timestamp ) Liefert den SQL Code für die Darstellung des Zeitstempels, der als Argument im ISO-Format yyyy-mm-dd hh24:mm:ss erwartet wird. Für Oracle könnte dies sein TO_DATE('2007-07-31 12:44:22', 'yyyy-mm-dd HH24:MI:SS'). 6.6 %cast( String expression ) Liefert die SQL-Funktion für einen Konvertierungsausdruck des im Argument übergebenen Datentypnamens. VARCHAR, CHARACTER and INTEGER sind unterstützte Datentypnamen. 6.7 %updlock() Liefert die SQL-Syntax für eine Sperre, z.B. ist dies für Oracle FOR UPDATE. 7 Tracing Die SOSConnection-Klassen unterstützen ein einheitliches Tracing: durch Setzen der logLevel Eigenschaft im verwendeten Logger wird die Protokollierungstiefe eingestellt. Ab Stufe 6 werden alle Methodenaufrufe und Parameter von SOSConnection-Klassen protokolliert. Ab Stufe 8 werden auch methodeninterne Datenbankaufrufe protokolliert. 8 Profiling Mit der Klasse SOSProfiler steht ein Instrument zur Performance-Messung und zur Fehlersuche in SQLStatements zur Verfügung. Alle SOSConnection-Klassen sind für Profiling vorbereitet und liefern pro Methodenaufruf das Intervall zwischen Beginn der Ausführung eines SQL-Statements und dem Verlassen der Methode in Millisekunden. Eine vergleichende Messung von Anwendungen unter Last ist dadurch möglich. Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 14 Die Klasse SOSProfiler ist separat dokumentiert. Das Profiling wird durch Zuweisung eines Profiler-Objekts über die Methode setProfiler() einer SOSConnection-Klasse aktiviert. 9 Konfigurationsdatei Die Konfiguration der Datenbankverbindung erfolgt über eine Einstellungsdatei. Deren Name wird der statischen Methode SOSConnection.createInstance() übergeben, die eine Instanz einer entsprechenden abgeleiteten Klasse von SOSConnection erzeugt. Die Einstellungsdatei enthält durch Zeilenumbrüche getrennte Name-Wert Paare der Form name=wert Folgende Parameter sind zu setzen: Parameter class= driver= Wert SOS Klasse für die Datenbankverbindung • MSSQL: SOSMSSQLConnection • MySQL: SOSMySQLConnection • Oracle: SOSOracleConnection • DB2: SOSDB2Connection • Firebird: SOSFbSQLConnection • PostgreSQL: SOSPgSQLConnection • ODBC: SOSODBCConnection JDBC-Treiber für die Datenbankverbindung • MSSQL: com.microsoft.jdbc.sqlserver.SQLServerDriver (nur SQL 2000) • MSSQL: com.microsoft.sqlserver.jdbc.SQLServerDriver (SQL 2005, 2000) • MySQL: com.mysql.jdbc.Driver • Oracle: oracle.jdbc.driver.OracleDriver • DB2: com.ibm.db2.jcc.DB2Driver • Firebird: org.firebirdsql.jdbc.FBDriver • PostgreSQL: org.postgresql.Driver • ODBC: sun.jdbc.odbc.JdbcOdbcDriver url= JDBC-URL zur Datenbank user= Name des Datenbankbenutzers password= Kennwort des Datenbankbenutzers 10 Besonderheiten beim Verbindungsaufbau Um unabhängig von Einstellungen der Datenbank oder des Datenbank-Clients zu sein, werden beim Verbindungsaufbau durch die SOSConnection-Klassen einige Einstellungen explizit gesetzt: 10.1 • MSSQL Transaction Isolation Level: TRANSACTION_READ_COMMITTED Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 15 • Select Method: Cursor • Datumsformat ymd (ISO-Datumsformat) • Sprache: British (für Zahlenformatierungen) • LOCK_TIMOUT 3000 (Es wird 3000ms gewartet, falls auf eine gesperrte Tabelle zugegriffen werden soll) 10.2 MySQL • Transaction Isolation Level: TRANSACTION_READ_COMMITTED (Serializable ist in MySQL InnoDB falsch implementiert) • SQL_Mode='ANSI_QUOTES' (client-seitiger SQL Kompatibilitätsschalter) 10.3 Oracle • Transaction Isolation Level: TRANSACTION_SERIALIZABLE • Datumsformat: yyyy-mm-dd hh24:mm:ss (ISO Datumsformat) • Zahlen: . als Dezimalzeichen 10.4 • 10.5 • 10.6 DB2 Transaction Isolation Level: TRANSACTION_READ_COMMITTED Firebird Transaction Isolation Level: TRANSACTION_REPEATABLE_READ PostgreSQL • Transaction Isolation Level: TRANSACTION_REPEATABLE_READ • Datumsformat: yyyy-mm-dd hh24:mm:ss (ISO Datumsformat) • Zahlen: . als Dezimalzeichen 11 Wie werden weitere Datenbanken angeschlossen? Beachten Sie bitte die folgenden Hinweise, falls Sie planen SOSConnection durch eigene abgeleitete Klassen für andere Datenbanken zu erweitern. 11.1 Implementierung der Konstruktoren Alle Konstruktor-Methoden der Basisklasse müssen implementiert werden. Die nachfolgenden Beispiele gehen von einer abgeleiteten Klasse mit dem Namen SOSMyDatabaseConnection aus: Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 16 11.1.1 public SOSMyDatabaseConnection() 11.1.2 public SOSMyDatabaseConnection(Connection connection, SOSLogger logger) 11.1.3 public SOSMyDatabaseConnection(Connection connection) 11.1.4 public SOSMyDatabaseConnection(String configFileName, SOSLogger logger) 11.1.5 public SOSMyDatabaseConnection(String configFileName) 11.1.6 public SOSMyDatabaseConnection(String driver, String url, String dbuser, String dbpassword, SOSLogger logger) 11.1.7 public SOSMyDatabaseConnection(String driver, String url, String dbuser, String dbpassword) 11.2 Implementierung abstrakter Methoden der Basisklasse Folgende abstrakte Methoden müssen implementiert werden: 11.2.1 public void connect() Baut die Verbindung zur Datenbank auf. 11.2.2 public void prepare(Connection connection) Diese Methode wird bei connect() aufgerufen und zum Senden einleitender Statements verwendet, z.B. zur Festlegung des Dezimalzeichens für die Zahlendarstellung, des Datumsformats und des gewünschten Transaktionsisolationslevels. Eine leere Implementierung ist zulässig. 11.2.3 protected boolean prepareGetStatements(StringBuffer contentSB, StringBuffer splitSB, StringBuffer endSB) Die Methode wird eingesetzt, um das Verhalten des SQL Statement Parsers in der Basisklasse SOSConnection für mehrere oder mehrzeilige Statements anzupassen. Beachten Sie bitte, dass Benutzer der Klasse nicht nur SELECT Statements verwenden, sondern mit der Klasse Tabellen und Prozeduren, Funktionen etc. einrichten. Der Parser muss daher die Statements analysieren und ggf. isolieren bevor sie ausgeführt werden. Diese Methode wird verwendet, um die Zeichenfolgen festzulegen, die mehrere Statements voneinander trennen bzw. ein Statement terminieren. Für Oracle ist die Trennzeichenfolge "\n/\n" (new line, "/" gefolgt von new line) ohne Terminierungszeichenfolge. Für MySQL ist dies "\n\\\\g\n" (new line, "\g" (mit verdoppelten backslashes) gefolgt von new line) als Trennzeichenfolgen und "\n\\g\n" als Terminierungszeichenfolge. 11.2.4 public String getLastSequenceQuery(String sequence) Liefert den SQL Code, der den letzten Wert liefert, der in ein Feld vom Typ Autoincrement eingefügt wurde. 11.2.5 public String[] getReplacement() Liefert einen Array von Strings mit SQL Funktionen für %lcase, %ucase, %now, %updlock, siehe Kapitel SQL Funktionen. Software- und Organisations-Service GmbH 14. August 2007 Connection - Zugriffsschicht für Datenbanken 17 11.2.6 rotected String replaceCasts(String expression) Liefert die SQL Funktion für einen Konvertierungsausdruck des Datentypnamens im angegebenen Argument. VARCHAR, CHARACTER and INTEGER sind unterstützte Datentypenamen. Der Rückgabewert dieser Methode wird für die Pseudo-Funktion %cast verwendet, siehe Kapitel SQL Funktionen. 11.2.7 public String toDate(String dateString) Liefert die SQL Syntax für einen Datentyp Datum oder Zeitstempel mit dem angegebenen Wert. 11.3 Implementierung optionaler Methoden Die folgenden Methodenimplementierungen sind optional. Sie werden von SOSConnection implementiert und können ggf. von abgeleiteteten Klassen überschrieben werden. 11.3.1 protected GregorianCalendar getDateTime(String format) Liefert den aktuellen Zeitstempel der Datenbank als Calendar Objekt. 11.3.2 public Vector getOutput() Liest die Ausgaben, die von der Datenbank als Antwort auf Statements erzeugt wurden. Für Oracle verwendet diese Methode das Paket dbms.output. 11.3.3 public int parseMajorVersion(String productVersion) Extrahiert die Hauptversionsnummer des DBMS aus der Produktkennzeichnung. Die Basisklasse implementiert dies durch Extrahieren der Zahl, die vor dem ersten Punkt der Produktkennzeichnung auftritt. 11.3.4 public int parseMinorVersion(String productVersion) Extrahiert die Nebenversionsnummer des DBMS aus der Produktkennzeichnung. Die Basisklasse implementiert dies durch Extrahieren der Zahl, die nach dem ersten Punkt der Produktkennzeichnung auftritt. Software- und Organisations-Service GmbH 14. August 2007