KLinform: Anbindung externer Firmenstammdaten
Transcription
KLinform: Anbindung externer Firmenstammdaten
Projektarbeit „KLinform: Anbindung externer Firmenstammdaten an KLinform“ Younous Elmoustafid AG Integrierte Kommunikationssysteme – ICSY Fachbereich Informatik Universität Kaiserslautern Betreuer :Prof.Dr.P.Müller Dipl.-Inform.Markus Hillenbrand „KLinform: Anbindung externer Firmenstammdaten an KLinform“ An Informationen zu gelangen ist Dank Internet immer einfacher geworden. Man braucht nur eine Suchmaschine anzuklicken, seine Suchkriterien in die Suchmaske einzugeben, und schon werden dutzende von Adressen einem vorgelegt. Damit ist man lange noch nicht am Ziel. Man soll sich durch den Web-Seiten Dschungel durchhangeln, bis man – mit großer oder kleiner Trefferquote - an seine gewünschte Information gelangt. Um die richtige Information zu finden, muß man sehr viel Zeit und Geduld mitbringen. Erst muß man seine Frage genau formulieren, und trotzdem muss man irrelevante Seiten heraus filtern. Eine Möglichkeit wäre es, wenn man ein Stadt-spezifisches Internet-Portal anbieten würde, so daß man diese Stadt-spezifischen Informationen wiederum mit weniger Auffand abfragen könnte. Kaiserslautern ist eine der Städte, die so ein Portal anzubieten versucht. Ihre Serverdatenbanken sollen alle Informationen von Kaiserslautern und Umgebung umfassen. Und diese Projektarbeit soll uns ein Stückchen näher ans Ziel bringen. Gegeben sind zwei Datenbankquellen: eine interne Datenbank (Klinform FirmenDatenbank) und mehrere externe Datenbanken ( darunter auch CSV-Dateien). Nun soll dem Benutzer die aktuellste Information zur Verfügung gestellt werden, ohne die genaue Herkunft dieser Information zu offenbaren. Da die aktuellsten Informationen immer aus der externen Datenbank stammen, muss die interne Datenbank immer manuell auf den neuesten Stand gebracht werden. Dies hat sich als sehr aufwendig erwiesen, deshalb müsste dieser Prozess automatisiert werden. Dieses automatisierte Anbinden externer Datenbanken zwecks Verfügbarkeit aktuellster Informationen verbirgt einige Schwierigkeiten, da die Datenbanken unterschiedlich sind, und zwar in dem was sie anbieten, d.h. verschiedene Inhalte mit verschiedenen Tabellen und Spaltennamen von verschiedenen Herstellern, und auch in der Weise , in der sie angeboten werden, andere Software, andere Treiber etc... Die vorliegende Ausarbeitung stellt eine Lösung vor, die ganzen Schwierigkeiten zu überwinden. Hierfür wurden mehrere Schritte benötigt, um dies zu realisieren. Dazu wurden Rahmenbedingungen abgearbeitet, Anforderungsanalyse erstellt und schließlich die Implementierung realisiert. 2 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ Inhaltsverzeichnis 1.Einführung 1.1 Klinform-Portal für die Region Kaiserslautern 1.2 Ziele der Projektarbeit 2. Systemanalyse 2.1 Interne Datenbank 2.2 Externe Datenbanken und Externe Files 3. Entwicklung des Algorithmus 3.1 Flussdiagramm 3.2 API der allgemeine Fall 3.3 Zusammenfassung 4. Anwendung des Algorithmus 4.1. Ein Einblick in die Klassen der API 4.2. Schritte innerhalb der API 5. Beispiel zweier Abgleiche: Kommentar: gehört in den Anhang 5.1 File Abgleich 5.2 Der Datenbanken-Abgleich 5.3 Zusammenfassung 6.Anhang 7. Literatur und links 3 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ 1. Einführung In der heutigen Zeit, kann man viel, sehr viel, über die ganze Welt, durch das Internet, erfahren. Vor allem ein Ort, eine Fabrik, eine Universität, eine Firma oder ein Institut, das im Internet nicht präsent ist, ist nicht mehr zeitgemäß und verzichtet auf eine neue und effiziente Art, sich einfacher seinen Kunden, seinen Touristen zu präsentieren. Eine Stadt ist natürlich nicht ausgeschlossen von dieser Entwicklung, denn je einfacher man Informationen über diese Stadt im Internet kriegen kann, sei es das nächst gelegene Krankenhaus, Schule oder Kindergarten oder die gerade laufenden Veranstaltungen, desto wichtiger ist es, daß das ganze zusammengefaßt und kompakt geschieht, am besten über ein Internet-Portal. 1.1 KLinform-Portal für die Region Kaiserslautern Das hat sich Kaiserslautern auch ans Herz gelegt, und will sich auch dem Rest der Welt online präsentieren. Diese Aufgabe verlangt natürlich sehr viel Arbeit und Geduld und vor allem (maßgeschneiderte) Informationen aus und über die ganze Region. Um dies zur Realität zu begleiten, wurde ein Konzept durchdacht. Hier ein Auszug zu diesem Projekt aus der KLinform-Portal-Projekt-Broschüre [1] Das Konzept dazu wurde von einer Projektgruppe aus Wissenschaft, Wirtschaft und Verwaltung in Kaiserslautern erarbeitet. Mit dem Multimedia-Preis des Landes Rheinland-Pfalz hat das Konsortium KLinform eine führende Rolle bei der Entwicklung neuer Online-Dienste übernommen. Die Idee der Orientierung an Lebenslagen stellt eine neue und zugleich herausfordernde Sicht auf die vielfältigen und doch weit vermaschten Informationen, die in der Region angeboten werden, dar. Die Abbildung der Lebenslagen heißt keinesfalls nur eine weitere Zusammenstellung von Internetadressen, sondern die Aufbereitung und Integration von Information und die Verwendung intelligenter Assistenten zur Präsentation und Unterstützung der Benutzer. Nachfolgend sollen zwei der zentralen Konzepte näher erläutert werden, durch die sich „KLinform“ von anderen Portalseiten abhebt: 1. durch das Lebenslagenkonzept 2. das Personalisierungskonzept 1.1.1. das Lebenslagen-Konzept Eine umfassende Benutzerführung, unterstützt durch intelligente Assistenten, soll allen Nutzerschichten die Möglichkeiten des neuen Mediums erschließen. Im Rahmen des Lebenslagenkonzeptes werden dazu zunächst Lebenslagen definiert. Darunter versteht man die für eine Aufgabenstellung typische Abfolge von Durchführungsschritten. Parallel dazu werden die vielfältigen Anbieter-Informationen und -Dienstleistungen kategorisiert und zu Einheiten zusammengefasst. Nachdem diese beiden Schritte abgeschlossen sind, können den einzelnen Durchführungsschritten einer Lebenslage spezifische Informationskategorien zugeordnet werden. 4 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ Der Benutzer kann nun Schritt für Schritt durch eine Lebenslage navigieren und erhält so immer nur genau die gerade benötigten Informationen übersichtlich angezeigt. Dieser Ansatz ist viel weitreichender als nur eine weitere Zusammenstellung von Internetadressen; sie ermöglicht dem Benutzer, sich auf sein eigentliches Problem zu konzentrieren. Er kann sicher sein, dass kein wesentlicher Aspekt bei der Planung und Durchführung einer „Lebenslage“ vergessen wird. Ein echter Mehrwert also, der sich positiv auf die Nutzung des Angebots auswirken wird!. 1.1.2. Das Personalisierungs-Konzept Ein weiterer wichtiger Aspekt, um die Attraktivität eines Portals zu steigern, ist die Möglichkeit zur individuellen Gestaltung des Portals. Für einen Benutzer ist es sicherlich von Vorteil, wenn sich die Wettervorhersage standardmäßig auf seinen Wohnort bezieht oder er automatisch aktuelle Veranstaltungshinweise für seine Hobbies per E-Mail zugeschickt bekommt. Genauso werden ihm bei Anfragen an Händler nur solche aufgezeigt die direkt um seine Postleitzahl ansässig sind. Die Stärke des Konzepts leitet sich unter anderem aus dem im wesentlichen regionalen Fokus der Anwendungen und Dienstleistungen ab. Um die ganzen Informationen dann ihrem Surfer zur Verfügung zu stellen, war es erforderlich, alle möglichen Informationen zur Stadt und Umgebung zu sammeln. Da die Informationen aus verschiedenen Quellen kommen, ist die Aktualität der Informationen nur zu gewährleisten, wenn man diese Quellen an die Klinform Firmen-Datenbank anbindet; Das erspart dem Surfer dann die Qual des Suchen, denn in dem Portal sind eben (fast) alle aktuellen Informationen enthalten. Das Problem bei dieser Aufgabe ist, dass die Datenbanken keine einheitliche Struktur haben, und keine einheitliche Software benutzen, zum Beispiel ist die eine Datenbank eine Oracle, die andere eine PostgreSQL, und berücksichtigen soll man natürlich auch csv-dateien, die auch mit der internen Datenbank abgeglichen werden wollen. Das würde bei Einzellösungen zu einer riesigen Anpassungsarbeit führen. 1.2 Ziele der Projektarbeit Im Folgenden ein Teil aus der Aufgabenstellung: Im Projekt KLinform existiert eine Firmendatenbank, in der Informationen zu Firmen und Institutionen aus dem Landkreis Kaiserslautern hinterlegt sind. Diese Informationen werden von KLinform in den verschiedensten Modulen ausgelesen. Eine ständige Wartung und Pflege dieser Daten ist sehr aufwändig. Deshalb sollen nach Möglichkeit externe Datenquellen erschlossen und an KLinform angebunden werden. Eine dieser externen Quellen ist die Handwerker-Datenbank des Projektes „Pfalzhandwerk24“. Um diese Anbindung zu ermöglichen, muß die schon vorhandene Datenbank erweitert werden. Dazu muß der Umfang der in den Tabellen eingetragenen Daten überprüft und ggf. erweitert werden. Weiterhin müssen Programmteile entwickelt werden, die die Aktualisierung der KLinform Daten übernehmen. Eine entsprechende Schnittstelle nach außen ist also zu spezifizieren. Hierbei ist zu beachten, daß die externen Quellen neue Einträge in KLinform vornehmen als auch alte löschen können. Die Anbindung 5 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ externer Datenbanken geschieht über eine Art „Abgleicher“-Modul, das die Daten der externen Datenbank mit der von KLinform abgleicht, d.h. neue Einträge werden hinzugefügt, entfallene gelöscht oder vorhandene geändert. In der Datenbank muß ein Hinweis darauf enthalten sein, dass diese Daten extern geändert werden können und nicht über KLinform. Für das Einlesen einer CSV Datei ist eine Java-Applikation zu schreiben, die die enthaltenen Daten mit denen in der Datenbank abgleicht. Hier reicht ein Vergleichen der eingetragenen Firmennamen und Adreßdaten aus. Rückfragen an den eintragenden Administrator sind dort angebracht, wo ein automatischer Abgleich nicht möglich ist. Abgleich er für DBx Firmendaten -bank DBx API CSV Datei 6 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ 2. Systemanalyse Dieses Kapitel beschäftigt sich mit dem, was zur Realisierung dieser Aufgabe zur Verfügung steht. Also, mit den Datenbanken generell, mit ihrer Software, mit der Umgebung, in der man arbeitet und vor allem mit den Problemen, auf die man stößt, um die externen Datenbanken oder Files zu homogenisieren. 2.1 Interne Datenbank Bei der internen Datenbank handelt es sich um die Klinform Firmen-Datenbank, sie wird im Laufe dieser Ausarbeitung mal intern mal Klinform genannt, aber dies ist die interne Datenbank, mit der externe Datenbanken abgeglichen werden sollen. Sie hat eine feste Struktur (zum Beispiel: enthält 28 Spalten, ihre verschiedene Datentypen sollen auch mit berücksichtigt werden). Um diesen Abgleich einwandfrei durchführen zu können sollen die anderen Datenbanken auch die gleiche Struktur haben. Je nach Bedarf sollen die Spaltennamen gemappt und die Datentypen gecastet werden. Das wird ausführlich beim homogenisieren der Datenbanken erklärt. Id 0 Name1 Name2 1 2 Strasse PLZ 3 4 Ort 5 Telefax Bild Email URL Shopurl 9 10 11 12 13 Postfach 6 Postfachplz 7 Öffnungszeiten 14 Beschreibung Leistungen 15 Telefon 8 16 AnfBuchSt abe Sw0 Sw1 Sw2 Sw3 Sw4 Sw5 Sw6 Sw7 Sw8 Sw9 17 18 19 20 21 22 23 24 25 26 27 Bei der internen Datenbank wurde PostgreSQL Version 7 verwendet, die Datenbankanbindung erfolgt mittels JDBC , und die Implementierungssprache ist Java. Als Datenbank wird PostgreSQL eingesetzt. PostgreSQL ist eine Verbesserung des POSTGRES-Datenbank-Managementsystems, ein "Next-Generation" DBMSForschungsprototyp. Die Datenbank ist aktuell für alle erdenklichen Systeme und Plattformen verfügbar. Während PostgreSQL das leistungsfähige Datenmodell und die reichhaltigen Datentypen von POSTGRES beibehält, ersetzt es die PostQuelAbfragesprache durch eine ausgedehnte Teilmenge von SQL. PostgreSQL ist genau so wie Linux frei und der komplette Quellcode ist verfügbar, und daher sehr beliebt. Als Schnittstellen stehen hauptsächlich ODBC und JDBC zur Verfügung. Implementierungssprache ist Java, aber wieso ausgerechnet Java? Die von Sun entwickelte Programmiersprache Java hat sich heute zu einem QuasiStandard im Internet entwickelt. Auch für Anwendungen wird sie zur Zeit immer mehr eingesetzt. Java ist eine plattformunabhängige, kostenlose und vollständig objektorientierte Programmiersprache. Die Plattformunabhängigkeit wird durch einen zweistufigen 7 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ Compiler erreicht. Der Entwickler kompiliert seinen Quelltext in einen sogenannten Bytecode. Diesen Code kann er unbedenklich ausliefern. Von der Java Virtual Machine wird dieser Bytecode dann auf der Zielmaschine ausgeführt, also interpretiert. Die Virtual Machine gibt es mittlerweile für jedes Betriebsystem und ist in den meisten Browsern und Betriebsystemen fest integriert. Ihr großes Manko ist , daß sie etwas langsamer ist als andere Programmiersprachen . Auch sind mittlerweile JIT, also Just in Time Compiler verfügbar, die den Bytecode auf der Zielmaschine zum Beispiel bei der Installation in die Maschinensprache kompilieren. Da KLinform- Betreiber keinen Einfluß auf die Plattformen der externen DatenbankBetreiber haben, und in der Zeit von globalen, stark heterogenen Netzwerken macht es Schwierigkeiten ein Programm zu schreiben, das auf allen Plattformen läuft. Es bestand also eine Nachfrage nach einer Umgebung zur Entwicklung moderner, portabler Software. Java hat sich in dieser Hinsicht etabliert und ist die ideale Lösung für dieses Problem . Hier sind die Vorteile der Programmiersprache Java zusammengefasst: • • geringer Administrationsaufwand • Änderungen des Programms nur auf dem (WWW-)Server • kein besonderer Datenbanktreiber auf dem Client nötig geringere Entwicklungskosten aufgrund ihrer Plattformunabhängigkeit. Neben Java wird natürlich auch ein Programm zur Herstellung der Verbindungen zu den Datenbanken, zwecks Vergleich dieser Datenbanken, bzw. um Informationen zu und über diese Datenbanken zu holen; hierfür wurde JDBC gewählt. JDBC ein kleiner Ausblick JDBC (Java-Database-Connectivity) ist ein von Sun entwickeltes Paket Java-API (Application Programming Interface) zur Ausführung von SQL-Anweisungen (Standard Query Language). Es besteht aus einer Menge von Klassen und Schnittstellen, die in der Programmiersprache Java geschrieben sind. JDBC bietet ein Standard-API für Entwickler von Datenbankwerkzeugen und ermöglicht das Schreiben von Datenbankanwendungen unter Verwendung eines puren Java-APIs. Durch Verwendung von JDBC ist es einfach, SQL-Anweisungen an nahezu jede relationale Datenbank zu senden. Mit anderen Worten, mit dem JDBC-API ist es nicht nötig, ein Programm für den Zugriff auf eine Oracle-Datenbank zu schreiben, ein andres Programm für den Zugriff auf eine PostgreSQL-Datenbank usw. Man kann mit Hilfe des JDBC-APIs ein einziges Programm schreiben und dieses wird in der Lage sein, SQL-Anweisungen an die entsprechende Datenbank zu senden. Und mit einer in Java geschriebenen Anwendung muss man sich auch nicht um das Schreiben verschiedener Anwendungen auf verschiedenen Plattformen kümmern. Die Kombination von Java und JDBC ermöglicht es dem Programmierer, das Programm einmal zu schreiben und es überall laufen zu lassen. JDBC setzt auf dem X/OPEN SQL-Call-Level-Interface (CLI) auf und besitzt damit die gleiche Basis wie die ODBC-Schnittstelle. 8 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ JDBC definiert Objekte und Methoden, mittels derer es dem Programmierer ermöglicht wird, in der Applikation den Zugriff auf darunterliegende Datenbanken zu realisieren. Der Zugriff erfolgt in der folgenden Weise: * * * * * Herstellung einer Verbindung zur Datenbank über den entsprechenden JDBC-Treiber für das verwendete DBMS Erstellung eines Statement-Objektes Weitergabe des auszuführenden Statements über das Statement-Objekt an das darunter liegende DBMS Abholung der Ergebnisse über die Ergebnisdatensätze Schließen der Verbindung zur Datenbank Ablauf einer Datenbankabfrage[6] 1.Treiber laden und Verbindung zur Datenbank herstellen Zuerst muss man eine Verbindung zu einem DBMS herstellen, das man benutzen möchte. Dazu sind zwei schritte nötig: Laden des Treibers und das Herstellen der Verbindung. Class.forName(driver); Connection conn=DriverManager.getConnection(URL); Beispiel: * OracleDatenbank: String HOST = "131.246.200.59"; String PORT = "1521"; String DBNAME = "zmh"; String TNSNAME = "(DESCRIPTION=(ADDRESS=(HOST="+HOST+")"+ "(PROTOCOL=tcp)(PORT="+PORT+"))"+ "(CONNECT_DATA=(SID="+DBNAME+")))"; String URL = "jdbc:oracle:thin:@"+TNSNAME; db2 = new DbConnect("oracle.jdbc.driver.OracleDriver",url,"Log in","passwort"); } * PostgreDatenbank String dbDriver = "org.postgresql.Driver"; String dbURL="jdbc:postgresql://shadow.informatik.unikl.de/DatenbankName "; String userName = "login" String password = "passwort" db1 = new DbConnect(String dbDriver,String dbURL,String userName,String password) 2.Statement erzeugen und SQL-Abfrage Ein Statement-Objekt sendet die SQL-Anweisung an das DBMS. Man erzeugt ein Statement-Objekt und führt es dann aus, indem man die der SQL-Anweisung entsprechende auszuführende Methode mitgibt, die man versenden möchte. 9 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ Zum Einrichten eines Statement-Objekts benötigt man eine aktive Verbindung. Statement stmt = con.createStatement(); Zu diesem Zeitpunkt existiert stmt aber es hat keine SQL-Anweisung, die es an das DBMS weiterleiten könnte. Das Ausführen einer SQL-Anweisung erfolgt wie folgt: //StatementObjekte erzeugen Stmt = Conn.createStatement(); //setze sql query um und erhalte ein Resultset ResultSet rs = Stmt.executeQuery(sql); String sql= “SELECT name1, url FROM firma “ Da die Tabelle Firma Informationen enthält, kann man mit der SELECT-Anweisung auf diese Information zugreifen, und die Informationen entsprechend seiner Wünsche dann ausgeben lassen. 3. Ergebnisse auslesen JDBC gibt die Werte in einem ResultSet-Objekt zurück; Hier ist eine Instanz der Klasse ResultSet nötig, in der dann die Ergebnisse enthalten sind. Der folgende Quelltext demonstriert die Deklaration desResultSet-Objeks rs und die Zuweisung der Ergebnismenge, wenn man z.B. die Namen und die dazugehörenden URLs in dieser Klinform Firma-Datenbank wissen möchte. ResultSet rs = Stmt.executeQuery(“SELECT name1, url FROM firma “); Die Variable rs enthält nun die Zeilen mit den Namen und den URLs der Firmen. Um darauf zugreifen zu können, muss man sich mit einem Cursor durch das ResultSet bewegen. Anfangs steht dieser noch über der ersten Zeile. Bewegen kann man den Cursor mit der Methode next( ). Der erste Aufruf von next( ) bewegt den Cursor in die erste Zeile des ResultSetObjekt und durch jeden weiteren Aufruf wird der Cursor eine Zeile weiter bewegt. 4. Weitere Funktionen des JDBC Um diese Informationen zu bearbeiten, und die rows und Columns individuell anzusprechen , gibt es im JDBC sehr viele Möglichkeiten, die aber aufzulisten sprengt den Rahmen dieser Ausarbeitung, hier aber ein paar wichtige Befehle: ResultSetMetaData rsmetadata = rs.getMetadata(); enthält alle Metadaten-Informationen über die Ergebnismenge (ResultSet)rs, und die Methode getColumnCount gibt Auskunft darüber, wie viele Spalten die Ergebnismenge hat. int numberOfColumns = rsmetadata.getColumnCount(); 10 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ 2.2 Externe Datenbanken und Externe Files * Bei der externen beispielhaften Datenbank ging es um eine PostgreSQL Datenbank, die 15 Spalten beinhaltet, andere Datentypen besitzt. Hier sind sogar Informationen – die bei der internen Datenbank in einer Spalte vorhanden sind – auf mehrere Spalten verteilt. Um ein Beispiel zur Verdeutlichung zu nennen, muss man drei Spalten Landeskennung, Vorwahl und Telefon zusammenfügen, um die Spalte Telefonnummer zusammenzukriegen. Die Spalten der Beispiel(externe)Datenbank sehen so aus: SpaltenId Name MapOrder 0 Name Strasse Plz Ort Ortsteil Landeskennung 1 2 3 4 5 6 Vorwahl Telefon Telefax www mail Kontakt Mitarbeit erzahl Freitext 7 8 9 10 11 12 13 14 Hier merkt man schon , dass die interne Datenbank mehr Spalten hat als diese externe Datenbank. Beim Aufruf des externen Jobs( Job, der den abgleicht zwischen beider Datenbanken erledigt), müssen Sachen anpasst werden, bevor man den Abgleich fährt. Das wird natürlich anhand eines Beispiels deutlicher . * Die API soll auch in der Lage sein eine CSV-Datei mit der internen Datenbank zu vergleichen, neue Daten dieser Datei in die interne Datenbank einzufügen und andere Daten zu aktualisieren. Hier wird mit einer Beispiel-Datei gearbeitet; zuerst sollte die Architektur geändert werden (vom File zur Tabelle) um später dann angepaßt zu werden . 11 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ 3. Entwicklung des Algorithmus In diesem Kapitel geht es um den Algorithmus, angefangen mit einem Flussdiagramm als Veranschaulichung für die Grundschritte; weiter geht es mit der API im Falle einer Datei und im Falle einer Tabelle, und zum Schluss geht es um das Abgleichermodul; also was soll speziell dort angepasst werden bzw. was soll beachtet werden? 3.1 Flussdiagramm Externes File oder Externe DatBank Ja Externe Datenbank? API, speziell die Klasse StaticRecordSet. Zweck Kopie erstellen und einiges anpassen. Nein API, speziell die Klasse File2StaticRecor dSet .Zweck umwandeln in eine Tabelle. Spalten anpassen in der JobKlasse, dann Abgleich fahren Ergebnis bzw. Auswahlmodus anzeigen. 12 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ 3.2 API der allgemeine Fall Im Prinzip soll die API keinen Unterschied machen, ob es sich um eine Datei oder um eine Tabelle handelt; Bis auf ein einziger kleiner Unterschied, nämlich, in der internen Datenbank soll man Daten aus einer externen Datenbank einfügen, updaten und löschen können; dagegen Daten aus einem externen File nur einfügen und updaten, also der Löschvorgang ist hier nicht vorhanden bzw. nicht erlaubt. 3.2.1 API bei einem File Zuerst muss man auf die gleiche Stufe kommen, wie die einer externen Tabelle. Also bevor man mit dem Abgleich losgeht, ist es notwendig die Dateistruktur zu ändern, und die zu einer Tabelle zu führen; Das macht die API selbst, ohne dass der Endbenutzer was davon merkt; Denn eine Klasse ist in der API eingebaut, die nichts anderes tut, als diesen Vorgang zu vollbringen. Mit einem Beispiel wird der Übergang von einem File zu einer Tabelle besser und einfacher erklärt; Wichtig ist dass hier noch kein Abgleich stattfindet sondern lediglich die Strukturumwandlung. Hierzu wird eine Beispiel(CSV)- Datei verwendet. Um diesen Fall besser zu verstehen, wird die Datei im ursprunglichen Zustand gezeigt, und im Zustand nach dem Durchlauf der API. Diese Datei sah vorher so aus: name;strasse;plz;ort;ortsteil;vorwahl;telefon Immobilien Wenk GmbH;Riesenstr. 2;67655;Kaiserslautern;;(0631);36693-30 Immobilien Weiskircher GmbH;Rudolf-Breitscheid-Str. 66;67655;Kaiserslautern;;(0631);3110782 Immobilien Stranz;Ludwigstr. 40;67657;Kaiserslautern;;(0631);3606557 Immobilien Service Markham Inh. Anne Markham;Königstr. 123;67655;Kaiserslautern;;(0631);36299-0 Immobilien Mohler VDM;Wilhelmstr. 11;67655;Kaiserslautern;Spanien-Immob.;(0631);3605523 Immobilien Hoch;Riesenstr. 15;67655;Kaiserslautern;;(0631);93058 Immobilien Gödtel GmbH;Am Altenhof 17;67655;Kaiserslautern;;(0631);66766 Immobilien Czarnecki GmbH & Co KG;Kaiserbergring 30;67657;Kaiserslautern;;(0631);36254-0 Immobilien Bohrmann;Distelstr. 16;67657;Kaiserslautern;;(0631);97927 Immobilien Anspach-Olfers Anitau.Robert; Sonntagstr.12; 67661;Kaiserslautern;;(06301);1641 In der ersten Zeile sind die Namen der Spalten vorhanden wie: Name, Strasse, Ort .....die weiteren Zeilen zeigen dann den Inhalt der jeweiligen Spalten. Generell kann man in Dateien nach Firmen, Personen oder Immobilien suchen, das ganze kann aber nicht systematisch geschehen, da die Struktur dies nicht ermöglicht. Vor allem das automatische abgleichen der Daten mit den Daten anderer externer Quellen kann man nicht erreichen, hierfür ist eine andere 13 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ Struktur ausschlaggebend, nämlich die Struktur einer Tabelle; Um dahin zu kommen enthält die API eine extra (hierfür gedachte) Klasse namens Static2RS, die diese Arbeit möglich macht. Sie wandelt das File in eine Tabelle um. Die erste Ziffer der ersten Zeile entspricht der Spaltennummer. Die zweite Ziffer der ersten Zeile entspricht dem Namen. Die dritte Ziffer der ersten Zeile entspricht dem Datentypen (Beispiel: 5=CHAR; 12=Integer). [1,name,5][2,strasse,12][3,plz,12][4,ort,12][5,vorwahl,12] [6,telefon ,12] Die Folgenden Zeilen sind dann wie folgt dargestellt: [ZeilenNr, SpaltenNr, Inhalt der entsprechenden Spalte] [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ [ 1, 1, Immobilien Wenk GmbH] [ 1, 2, Riesenstr. 2][ 1, 3, 67655] 1, 4, Kaiserslautern] [ 1,5, 0631][1,6,36693-30] 2, 1, Immobilien Weiskircher GmbH][2, 2, Rudolf-Breitscheid-Str66] 2, 3, 67655][ 2, 4, Kaiserslautern] [2,5, 0631][2,6, 3110782] 3, 1, Immobilien Stranz] [ 3, 2, Ludwigstr. 40][ 3, 3, 67657] 3, 4, Kaiserslautern] [3,5, 0631][3,6, 3606557] 4, 1, Immobilien Service Markham Inh. Anne Markham] 4, 2, Königstr.123][4, 4, 67655] [ 4,4, Kaiserslautern] 4,5, 0631][4,6, 36299-0] 5, 1, Immobilien Mohler VDM] [ 5, 2, Wilhelmstr. 11][ 5, 3, 67655] 5, 4, Kaiserslautern] [5,5, 0631][5,6, 3605523] 6, 1, Immobilien Hoch] [ 6, 2, Riesenstr. 15][ 6, 3, 67655] 6, 4, Kaiserslautern] [ 6,5, 0631][6,6, 93058] 7, 1, Immobilien G<F6>dtel GmbH] [ 7, 2, Am Altenhof 17] 7, 3, 67655][ 7, 4, Kaiserslautern] [7,5, 0631][7,6, 66766] 8, 1, Immobilien Czarnecki GmbH & Co KG][ 8, 2, Kaiserbergring 30] 8, 3,67657][ 8, 4, Kaiserslautern] [8,5, 0631][8,6, 36254-0] 9, 1, Immobilien Bohrmann] [ 9, 2, Distelstr. 16] 9, 4, 67657] [ 4,4, Kaiserslautern] [9,5, 0631][9,6, 97927] 10, 1, Immobilien Anspach-Olfers Anita u. Robert] 10, 2, Sonntagstr. 12][ 10, 3, 67661][ 10, 4, Kaiserslautern] 10,5, 0631][ 10,6, 1641] In dieser neu strukturierten (Datei) Tabelle kann man sehr einfach Informationen suchen; Man kann diese Datei je nach Bedarf sortieren (Nach Buchstaben, Telefonnummern..) -- hierfür gibt es verschiedene Tools-- um einfacher und vor allem schneller seine Information zu kriegen, was nicht der Fall war in der alten Struktur. Man kann die Information auch gezielt ansprechen (löschen, ändern oder updaten (zum Beispiel mittels SQL, wenn man die Zeilennummer und die Spaltennummer kennt und die auch angibt). Generell übernimmt die API (bei einem File) dem Benutzer folgende Tätigkeiten: • Das Umwandeln von einem File zu einer Datenbank (Tabelle), denn da kann der Benutzer nichts anrichten, das soll automatisch geschehen. • Das Ausführen des Einfügens und des updaten, und vor allem der Verzicht auf die Aktion löschen, denn sie ist ja in diesem Falle nicht erlaubt. Dagegen ist das Anpassen der Spalten (Namen) bzw. die richtige Positionierung der Spalten nach wie vor dem Endbenutzer überlassen, das geschieht allerdings in einem extra (hierfür gedachten) Job (siehe Kapitel 5). 14 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ 3.2.2 API bei einer Datenbank Bei externen Datenbanken (Tabellen), übernimmt ( wie im Filefall zuvor auch ) die API die ganze Arbeit, abgesehen von den Anpassungen, auf die in dieser Ausarbeitung immer wieder hingewiesen wird, da sie unverzichtbar sind um vernünftige Ergebnisse zu realisieren. Denn, die Grundstruktur der miteinander zu vergleichenden Tabellen fast identisch ist. Diese Anpassungen geschehen allerdings im dazu gehörenden Job. Was macht aber diese API mit einer externen Datenbank? Ausführlicher wird das zwar erst im nächsten Kapitel erklärt, hier vorab aber ein paar Erläuterungen dazu. Wenn sich die externe Datenbank anmeldet, kriegt sie eine Identifizierungsnummer, die sie dann für immer bei der API identifiziert, diese Identifizierungsnummer ist eindeutig und nicht veränderbar. Das geschieht nur innerlich und nicht äußerlich; Da nach dem anmelden der externen Datenbank eine Kopie (so genannte StaticRecordSet) erstellt wird, die nach bestimmten Kriterien sortiert ist und mit anderen Informationen auch gefüttert wird, so das es später im Job einfacher wird für den Benutzer den Abgleich zu fahren. Diese (StaticRecordSet) Kopie wird immer aktualisiert, wenn sich das Original ändert, denn da wird vom externendatenbankbetreiber nichts in die Kopie geschrieben, oder geändert sondern natürlich ins original, der Rest geschieht dann über die API. Generell übernimmt die API (bei einer externen Datenbank) dem Benutzer folgende Tätigkeiten: • • Das erstellen einer Kopie auf der die ganzen Arbeiten (einfügen, updaten und löschen) gemacht werden. Das Ausführen des Einfügens , des updaten und des löschen; letzteres ist bei Datenbanken erlaubt. Das Anpassen der Spalten(Namen) bzw. die richtige Positionierung der Spalten bleibt wie im vorherigen Fall dem Endbenutzer überlassen, dies geschieht auch in einem extra (hierfür gedachten) Job (siehe Kapitel 5). 3.3 Zusammenfassung: In diesem Kapitel wurden ein paar Schritte erklärt, wie zum Beispiel der Vorgang wenn es um eine Datei geht, und der Vorgang bei einer Datenbank. Die anderen Schritte innerhalb der API werden später gezeigt und erklärt. Der Schritt von einer Datei in einer Tabelle wurde sehr ausführlich anhand eines Beispiels erklärt und gezeigt. Im nächsten Kapitel wird die API erklärt, wichtige Klassen erläutert und ihre Wirkung auf die Datenbanken dann anhand Beispiele besser erklärt. 15 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ 4. Anwendung des Algorithmus In diesem Kapitel wird die API erklärt, ihre wichtigen Methoden erklärt und ihre Arbeitsweise erläutert. Zuerst werden die Klassen einzeln beschrieben, und im zweiten Teil dann ihre Funktionsweise. 4.1. Ein Einblick in die Klassen der API Die API enthält 8 Klassen: Comparator, AutoRegister, AbstractJob, DbConnect, GrowableArray, KeyBoard, File2StaticRS und StaticRecordSet. Es werden auch die wichtigsten Methoden erwähnt; Diese Methoden werden natürlich auch von anderen Klassen aufgerufen und benutzt. AbstractJob: Diese Klasse ist das Grundgerüst für den Abgleichjob. Sie enthält mehrere Methoden, darunter die Methode getrsInternDb, die ein Subset der internen Datenbank einliest, um es später mit Hilfe der Methode compare mit dem von getrsExternDb eingelesenen Subset der externen Datenbank zu vergleichen. Weitere Methoden dieser Klassen sind z.B doUpdate und doDelete , die die Datensätze updaten bzw. löschen. AutoRegister: weiss über die verschiedenen Datenbanken. Denn, sie vergibt den Datenbanken bei ihrem ersten Anmelden eine eindeutige Nummer, die die dann ( für immer) behalten um damit identifiziert zu werden. Die interne Klinform FirmenDatenbank erhielt zum Beispiel die Identifikationsnummer 0. Comparator: Vergleicht die StaticRecordSets der internen und externen Datenbanken. Sie markiert die Datensätze, damit sie später eingefügt, geupdatet oder gar gelöscht werden. Enthält wichtige Methoden wie compare, die bei AbstractJob auch aufgerufen wird, und schon beschrieben worden ist, und compareRows, die ( wie der Name sagt) die Zeilen der internen mit denen der externen Datenbank vergleicht. DbConnect: Diese Klasse stellt die Verbindung mittels JDBC zu den Datenbanken her. Sie abstrahiert die Daten und führt Select-Anweisungen aus. Enthält die Methode getStaticRecordSet , die die Daten in einem Statischen Datentyp speichert. Weitere Methoden sind deleteRow und insertRow , die Zeilen löschen oder auch einfügen. File2StaticRS: Diese Klasse wrappt die Importfiles. Sie wandelt diese Dateien bzw. ihre Struktur in die Struktur einer Tabelle, um somit die einfüg- und updateverfahren zu vereinfachen. Unter anderem enthält sie die Methoden getColAmount, getColumns, getRows und loadFile zum Laden des Files , die bearbeitet werden soll. GrowableArray: Diese Klasse ist ein wachstumsfähiges Array, weil man nicht weiss, wie viele Datensätze die verschiedenen Datenbaken haben. KeyBoard: Diese Klasse ermöglicht eine Tastaturabfrage. StaticRecordSet: Diese Klasse macht aus einem Datensatz ein StaticRecordSet, d.h eine Kopie, auf der dann die Anpassungen stattfinden. Enthält verschiedene Methoden, darunter die castColumnMethode , diese Methode castet Typen (der externen Datenbankenspalten) nach den Typen (der internen Datenbankspalten) z.B 16 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ „Strings die Zahlen beinhalten nach integer“ castColumn(int col,int newTyp). Eine andere Methode ist setColName, und ist für das Anpassen der Spaltennamen zuständig. 4.2. Schritte innerhalb der API Innerhalb der API verlaufen manche Schritte um die externen Datenbanken so zu präparieren, dass der Abgleich dann einwandfrei und glatt läuft, in dem sie die StaticRecordSets zueinander homogenisiert. Im Prinzip ist die Vorgehensweise bei einem File oder bei einer Tabelle gleich, mit der Ausnahme , dass beim File vorher der Vorgang File Æ Tabelle gemacht wird. Die interne Datenbank enthält (wie bereits erwähnt) 28 Spalten. Damit man später eindeutig unterscheiden kann, ob die Information , die man hat, intern oder extern sind, will heißen, ob die Informationen aus der Klinform Firmen-Datenbank stammen oder aus irgend einer externen Tabelle, wurde eine extra Spalte kreiert, in der dann die Informationsquelle eindeutig erkennbar ist. Diese Spalte heißt Datenstamm und hat für die interne Datenbank dann die eindeutige Zahl 0 . Die Kopien der Datenbanken e(also die StaticRecordSets) erhalten auch diese Extraspalte, die ihre Quellen auch identifiziert. Dieser Extraspalte kriegt dann eine Zahl zugeordnet und zwar automatisch durch eine AutoRegisterKlasse. Schritt1: Datenbank Mache eine Kopie; erhalte Antwort in Tabellen Form. Lege die primärschlüsseln fest. speichere die Daten, und erhalte StaticRecordSet. Die interne Datenbank erhält die 0 als Id-Nummer. Es wird nur mit dem StaticRecordSet gearbeitet. Denn , das ermöglicht ein von den Datenbankquellen unabhängiges Arbeiten insbesondere das Navigieren. Schritt2: Mache ein Select über die für den Abgleich relevanten Daten. Das Ergebnis wird durch JDBC in einem ResultSet zurückgegeben und zwar in Tabellen Form. Übergebe das ResultSet, den MapOrder und die Primärschlüssel einem leeren StaticRecordSet, das daraus eine statische Kopie des ResultSets erzeugt, die von den Spalten nach dem MapOrder sortiert ist, und deren PrimaryKeyFelder in einem hashtable mit der zugehörigen Zeile verbunden sind. 17 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ Interne Datenbank HashTableId Array bestehend aus PrimaryKeys, in unserem Falle Name, Strasse und plz. Externe Datenbank HashTableId Array bestehend aus PrimaryKeys, in unserem Falle Name, Strasse und plz. Die Klasse hashtable stellt einen assoziativen Speicher dar, der Schlüssel auf Werte abbildet und über den Schlüsselbegriff einen effizienten Zugriff auf den Wert ermöglicht. Es werden immer zusammengehörige Paare von Daten gespeichert, bei denen der Schlüssel als Name des zugehörigen Wertes angesehen werden kann. Über den Schlüssel kann später der Wert leicht wiedergefunden werden. Also, anhand der Hashtable hat man einen schnellen Zugriff auf die Daten. Die Daten sind nun optimiert, aber wie verläuft das Einfügen, löschen und updaten? Anstatt der 3 Fälle einzeln zu betrachten, werden alle Fälle zusammenbetrachtet mit einigen Hinweisen. Angenommen, wir haben die interne Datenbank, 2 externe Datenbanken; In der einen externen sind Ärzte aus Hochspeyer, und in der anderen sind Ärzte aus Kaiserslautern enthalten, beide Datenbanken sollen dann angebunden werden, da Klinform auch diese Informationen enthalten soll. Der Verlauf des Abgleichs: Das erste Einfügen der Daten verläuft so: Die Daten werden eingefügt und sind schon alle ( in der letzten Spalte) gekennzeichnet, wo sie herstammen; Das passiert mit den Datensätzen beider externen Datenbanken. Werden die Datenbanken geändert, muss dann die Klinform auch aktualisiert werden. Angenommen ändert sich bei der Ärztedatenbank Hochspeyer etwas; Es werden aus der internen Datenbank nur die Datensätze geholt, die die Ziffer enthalten , die diese Datenbank dann identifiziert , praktisch ein Subset, bzw. eine „Tochter“Datenbank, die nur die Daten aus der Ärztedatenbank Hochspeyer enthält,; Man braucht hierfür nur ein Select Statement where DatenStamm = Nummer der Ärztedatenbank Hochspeyer (Diese Nummer ist eindeutig, und wird bei der ersten Anmeldung der Datenbank mittels der Klasse AutoRegister vergeben); also es kann keine Inkonsistenz geben. Mittels des Hashtables werden dann die Daten aus der Kopie der externen DB in dem Subset sehr schnell aufgefunden und markiert. Fehlt eine Zeile in dem Subset, dann wird sie natürlich eingefügt; Ist sie vorhanden, dann wird sie einfach überschrieben, das garantiert mir die Aktualität der Daten ohne einen weiteren Abgleich der jeweiligen Zeilen zu fahren. Sind alle Daten der externen Datenbank durch, werden dann alle restlichen Daten aus dem Subset wie folgt gelöscht! 18 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ Im Subset werden alle Daten, die neu eingefügt sind mit einer (z.B) 1 versehen. Im Subset werden alle Daten, die upgedatet worden sind mit einer (z.B) 2 versehen. Alle Daten, die weder eine 1 noch eine 2 enthalten, sind Daten, die mal in der externen Datenbank existiert haben, jetzt aber nicht mehr dort vorhanden sind. Da die Aktualisierung der externen Datenbanken nur extern geschieht, kann man dann die nicht mehr aktuellen Daten mit diesem Verfahren löschen. Dieses Verfahren wird genauso mit der Ärztedatenbank Kaiserslautern laufen und mit anderen externen Datenbanken auch. Beim File-Abgleich fehlt der Löschvorgang, da es nicht Bestandteil der ProjektArbeit war. Es darf also aus einer Datei nur eingefügt und geupdatet werden. Nach diesen Verfahren oder Schritten, wird jedes Subset aus der internen Datenbank wieder aktuell, somit auch die gesamte interne Datenbank. Im folgenden Flussdiagramm wird noch mal der Abgleich erklärt: 1 = Parameter extrahieren und Subset einlesen. 2 = Id abfragen 3 = Wenn in der extra hierfür kreierten Tabelle vorhanden(nichts machen). 4 = Wenn nicht vorhanden, dann eine neue anlegen. 5 = Selektiere z.B select * from extern DB 6 = Id der DB weitergeben 19 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ 4 Tabelle enthält DBs mit ihren Ids Interne DB Externe DB 3 2 2 Id da? 1 5 6 6 StatRecSet StatRecSet Transformiere StatRecSet: 1. Mapping 2. Casting Zu diesem Zeitpkt sind die SRS homogenisiert Compare Klasse Nicht angefasste löschen. Markierte bearbeiten: Einfügen oder updaten 20 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ 5. Beispiel zweier Abgleiche: Kommentar: gehört in den Anhang In diesem Kapitel werden zwei Beispiele zum Abgleichen File/interne Datenbank und extern/interne Datenbank gezeigt, mit Hinweisen auf die Änderungen , die der Anwender vornehmen und beachten muss. Angefangen mit dem Fileabgleich, danach kommt der Datenbankenabgleich. 5.1 File Abgleich Bitte beachten, die Stellen, die Fettmarkiert sind, sollen angepasst werden. package younousdbapp.jobs; import younousdbapp.*; //younousdbapp ist die API public class ExternFileJob extends AbstractJob{ public static void main(String[] a){ new ExternFileJob().start(); } public void start(){ DbConnect db1 = new DbConnect("org.postgresql.Driver","jdbc:postgresql://shadow.informatik. uni-kl.de/interneDatenBank","meinLogin","meinPassWort"); //standard, stelle Kontakt zur HauptDatenBank // lege Primary Keys fest int[] primaryKeys={1,3,4}; //*Name, Strasse und postleitzahl. // namen der Datenbanken String internDbTableName = "internDb"; //* zB Firma, in diesem Falle standard! //Bei einer Datei , gebe die Url der Datei an String externFileName = "/home/elmousta/csvDatei.csv"; //* nur csv-Dateien ! // id Fuer Externe Datenbank (DatenStamm) int externFileId = new AutoRegister(db1).getId("Externes_File"); //hole mir eine Eintrittsnummer bzw. Identifikationsnummer mit //Autoregister aus externtable! //ladeInterne Db // db1 -> Connection to DbIntern StaticRecordSet rsInternDb = getrsInternDb(db1,internDbTableName,primaryKeys,externFileId); //lade Externe Db // db2 -> Connection to DbExtern StaticRecordSet rsExternFile = getrsExternFile(externFileName,primaryKeys,externFileId); //vergleiche Dbs mit der Methode compare compare(rsInternDb,rsExternFile); // schreibe Unterschiede in die interne Datenbank this.doUpdateInsert(db1,internDbTableName,rsExternFile); 21 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ } Hier kommt mein Maporder für das File. CSV Datei ColName Name AnDerStelle 0 Straße 1 Plz 2 Ort 3 Ortsteil 4 Vor.von.Tel 5 Tel 6 //Diese Funktion liest das Subset ein! public StaticRecordSet getrsExternFile(String externFileName,int[] primaryKeys,int externFileId){ int[] mapOrder= new int[29]; // speichre erst mal alles auf -1 for(int i =0; i<mapOrder.length;i++) mapOrder[i]=-1; // Diese MapOrdner bezieht sich auf die Datei mapOrder[1]=0;//Die Spalte an der Stelle 0 Im FileMapOrder kommt an die Stelle //1 im DatenbankMapOrder mapOrder[3]=1;//Wie oben aber 1Æ3 mapOrder[4]=2;// 2Æ4 mapOrder[5]=3; // 3Æ5 mapOrder[8]=6; // 6Æ8 mapOrder[9]=5; // 5Æ9 StaticRecordSet rs= new File2StaticRS(externFileName,primaryKeys,mapOrder); // nun fasse die Vorwahl mit der TelNr Zusammen! // Beispiel, falls im File die Tel.Nummer in 2 Spalten aufgeteilt ist! for(int i=0; i< rs.getRowsAmount(); i++){ Object[] curRow = rs.getRow(i); String vorwahl =(String)curRow[9]; String telNr =(String)curRow[8]; curRow[8] = vorwahl + "-" + telNr; curRow[9] = null; } // Gilt sowohl für das File als auch für externe Datenbanken // Mapping mit names; das sind die endgültigen Spaltennamen! rs.setColName(0,"id"); rs.setColName(1,"name1"); rs.setColName(2,"name2"); rs.setColName(3,"strasse"); 22 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ rs.setColName(4,"plz"); rs.setColName(5,"ort"); rs.setColName(6,"postfach"); rs.setColName(7,"postfachplz"); rs.setColName(8,"telefon"); rs.setColName(9,"telefax"); rs.setColName(10,"bild"); rs.setColName(11,"email"); rs.setColName(12,"url"); rs.setColName(13,"shopurl"); rs.setColName(14,"oeffnungszeiten"); rs.setColName(15,"beschreibung"); rs.setColName(16,"leistungen"); rs.setColName(17,"anfangsbuchstabe"); rs.setColName(18,"sw0"); rs.setColName(19,"sw1"); rs.setColName(20,"sw2"); rs.setColName(21,"sw3"); rs.setColName(22,"sw4"); rs.setColName(23,"sw5"); rs.setColName(24,"sw6"); rs.setColName(25,"sw7"); rs.setColName(26,"sw8"); rs.setColName(27,"sw9"); rs.setColName(28,"datenstamm"); //Wo die Daten herkommen? Eine eindeutige Zahl! //Das Casten soll man nicht vergessen, je nach dem welche DatenTypen die //Spalten sind. // cast the id to Int rs.castColumn(0,rs.INT2); //cast sw0 bis sw9 to int2 for(int i=18; i< 28; i++){ rs.castColumn(i,rs.INT2); } // cast the AnfangsBuchstaben to Bpchar rs.castColumn(17,rs.BPCHAR); // fuelle die letzte spalte mit rsExternFileId // name rs.setColName(28,"datenstamm"); // cast rs.castColumn(28,StaticRecordSet.INT4); //fuelle for(int i=0; i< rs.getRows();i++){ rs.setElement(i,28,new Integer(externFileId)); } 23 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ // Frage nach Anzeige System.out.println("Externes File " +externFileName + " ausgelesen und homogenisiert."); System.out.println("Anzeigen?"); if(KeyBoard.readBooleanKeyb()) rs.show(); } return rs; 5.2 Der Datenbanken-Abgleich Die externe Datenbank sah vor Ausführen des Programms so aus: [Spaltennummer, Spaltennamen, Spaltentyp] [ 0, id, 4][ 1, name, 12][ 2, strasse, 12][ 3, plz, 12][ 4, ort, 12][ 5, ortsteil, 12][ 6, landeskennung, 12][ 7, vorwahl, 12][ 8, telefon, 12][ 9, telefax, 12][ 10, www, 12][ 11, mail, 12][ 12, kontakt, 12][ 13, mitarbeiterzahl, 4][ 14, freitext, 12] [Zeilennummer,Spaltennummer, Inhalt] [ 0, 0, 4365][ 0, 1, Bergbau AG][ 0, 2, Hubwagenweg 17][ 0, 3, 98765][ 0, 4, Hettenhausen][ 0, 5, Heine][ 0, 6, +49][ 0, 7, 06659][ 0, 8, 12345][ 0, 9, 67890][ 0, 10, http://www.heise.de][ 0, 11, hans@wurst.de][ 0, 12, Peter Maier][ 0, 13, 4711][ 0, 14, Keine hohe Akzeptanz in allgemeinen Bergbaukreisen!] [ 1, 0, 34][ 1, 1, Zillertaler Walzwerke oHG][ 1, 2, Meiserstr. 56][ 1, 3, 3456][ 1, 4, Milchhausen][ 1, 5, Huhndorf][ 1, 6, +44][ 1, 7, 04456][ 1, 8, 2353456][ 1, 9, 35623452435][ 1, 10, http://www.web.de][ 1, 11, hans@wurst.com][ 1, 12, Klaus Topp][ 1, 13, 9][ 1, 14, Nur in Europa taetig.] [ 2, 0, 567][ 2, 1, Spengler Kranarbeiten GmbH][ 2, 2, Blechhammerweg 15][ 2, 3, 67659][ 2, 4, Kaiserslautern][ 2, 5, null][ 2, 6, +49][ 2, 7, 0631][ 2, 8, 3737-3][ 2, 9, null][ 2, 10, www.spengler.de][ 2, 11, hans@spengler.de][ 2, 12, Hans Spengler][ 2, 13, 34][ 2, 14, Nur in der Westpfalz bitte.] [ 3, 0, 344][ 3, 1, Pfalztheater][ 3, 2, Willy-Brandt-Platz 4-5][ 3, 3, 67657][ 3, 4, Kaiserslautern][ 3, 5, null][ 3, 6, +49][ 3, 7, 0631][ 3, 8, 3675-0][ 3, 9, 3675-235][ 3, 10, http://www.pfalztheater.de][ 3, 11, info@pfalztheater.bvpfalz.de][ 3, 12, null][ 3, 13, 0][ 3, 14, ] Bei einer externen Datenbank ist vieles ähnlich wie bei der Datei oben. import younousdbapp.*; //import mein API public class FdbJob extends AbstractJob{ 24 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ //* macht klasse Ausfuehrbar! public static void main(String[] a){ new FdbJob().start(); } public void start(){ DbConnect db1 = new DbConnect("org.postgresql.Driver","jdbc:postgresql: //shadow.informatik.unikl.de/Datenbank","Login","passWort"); DbConnect db2 = new DbConnect("org.postgresql.Driver","jdbc:postgresql: //shadow.informatik.uni-kl.de/fdb","login","passwort"); // lege Primary Keys fest int[] primaryKeys={1,3,4}; // namen der Datenbanken String internDbTableName = "firma"; String externDbTableName = "companies"; // id Fuer Externe Datenbank (DatenStamm) holen! //int externDbId = new AutoRegister(db1).getId(externDbTableName); int externDbId = new AutoRegister(db1).getId("companies"); //int externDbId = new AutoRegister(db1).getId("externDb"); //ladeInterne Db // db1 -> Connection to DbIntern StaticRecordSet rsInternDb = getrsInternDb(db1,internDbTableName,primaryKeys,externDbId); //lade Extere Db // db2 -> Connection to DbExtern StaticRecordSet rsExternDb = getrsExternDb(db2,externDbTableName,primaryKeys,externDbId); //vergleiche Dbs compare(rsInternDb,rsExternDb); // schreibe Uterschiede in Inter this.doUpdateInsert(db1,internDbTableName,rsExternDb); this.doDelete(db1,internDbTableName,rsInternDb); } //Diese Funktion liest das Subset ein! public StaticRecordSet getrsExternDb(DbConnect db2,String externDbTableName,int primaryKeys,int externDbId){ //Select String sql = "select * from " + externDbTableName; 25 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ // lege Maporder fest! Wie oben aber jede externe Datenbank hat einen // anderen Maporder ColNames AnDerStelle ColNames AnDerStelle Id 0 Telefon 8 Name 1 Telefax 9 Strasse 2 www 10 Plz 3 Mail 11 Ort 4 Kontakt 12 Ortsteil 5 Mitarbeiter 13 Landeskennung 6 Freitext 14 Vorwahl 7 int[] mapOrder= new int[29]; // speichre erst mal alles auf -1 for(int i =0; i<mapOrder.length;i++) mapOrder[i]=-1; // Mapping mit Namen; das sind die endgültigen Spaltennamen! // Siehe Seiten 22 & 23 (das Fettgedruckte!). mapOrder[0]=0;// id -> id mapOrder[1]=1;// name -> name1 mapOrder[3]=2;// strasse -> stasse mapOrder[4]=3;// plz - plz mapOrder[5]=4;// ort - ort mapOrder[8]=8;// TelefonRufnummer - telefon mapOrder[9]=9;// Telefax - Telefax mapOrder[11]=11;// mail - email mapOrder[12]=10;// www - url mapOrder[16]=7;// Vorwahl - 16 Hilf - 8 mapOrder[17]=5;// ortsteil - 17 Hilf - 5 mapOrder[18]=6;// Landeskenunng - 18 Hilf - 8 mapOrder[20]=13;//mitarbeiterzahl - 20 Hilf - 15 mapOrder[21]=14;//Freitext - 21 Hilf - 15 mapOrder[22]=12;//Kontakt - 22 Hilf - 15 StaticRecordSet rs = db2.getStaticRecordSet(sql,primaryKeys,mapOrder); // Passe An //Diese Funktion liest das Subset ein! // nun fasse ich die LandesKennung mit Vorwahl mit der //TelNr Zusammen! for(int i=0; i< rs.getRowsAmount(); i++){ Object[] curRow = rs.getRow(i); String vorwahl =(String)curRow[16]; String telNr =(String)curRow[8]; String landeskennung =(String)curRow[18]; if(vorwahl == null)vorwahl =""; if(telNr == null)telNr =""; if(landeskennung == null)landeskennung =""; curRow[8] = landeskennung + vorwahl curRow[18] = null; curRow[16] = null; + telNr; } 26 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ // nun fasse ich den Ort mit dem Ortsteil zusammen! for(int i=0; i< rs.getRowsAmount(); i++){ Object[] curRow = rs.getRow(i); String ort =(String)curRow[5]; String ortsteil =(String)curRow[17]; if(ort == null)ort =""; if(ortsteil == null)ortsteil =""; curRow[5] = ortsteil + ort; curRow[17] = null; } // nun fasse ich die Spalten mitarbeiterzahl und Freitext zusammen! for(int i=0; i< rs.getRowsAmount(); i++){ Object[] curRow = rs.getRow(i); String mitarbeiterZahl ="" +((Integer)curRow[20]).intValue(); String freitext =(String)curRow[21]; String kontakt =(String)curRow[22]; if(mitarbeiterZahl == null)mitarbeiterZahl =""; if(freitext == null)freitext =""; if(kontakt == null)kontakt =""; curRow[15] = "Mitarbeiter : " + mitarbeiterZahl +" / freitext : " + freitext + " / kontakt : " + kontakt ; curRow[20] = null; curRow[21] = null; curRow[22] = null; } //Die endgültige Version der SpaltenNamen , identisch mit denen der internen //datenbank, // Mapping mit names Hier muss man den Maporder wieder // cast the id to Int rs.castColumn(0,rs.INT2); //cast swx to int2 for(int i=18; i< 28; i++){ rs.castColumn(i,rs.INT2); } // cast the AnfangsB to Bpchar rs.castColumn(17,rs.BPCHAR); // cast rs.castColumn(28,StaticRecordSet.INT4); //fuelle for(int i=0; i< rs.getRows();i++){ rs.setElement(i,28,new Integer(externDbId)); } 27 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ // Frage nach Anzeige System.out.println("Externe Datenbank " +externDbTableName + " ausgelesen und homogenisiert."); System.out.println("Anzeigen?"); if(KeyBoard.readBooleanKeyb()) rs.show(); return rs; } Nach den Anpassungen und Ablauf des Programms sieht dann die (StaticRecordSet) datenbank so aus: Geschildert sind dann [die Spaltennummer, Spaltenname, SpaltenTyp] [ 0, id, 5][ 1, name1, 12][ 2, name2, 12][ 3, strasse, 12][ 4, plz, 12][ 5, ort, 12][ 6, postfach, 12][ 7, postfachplz, 12][ 8, telefon, 12][ 9, telefax, 12][ 10, bild, 12][ 11, email, 12][ 12, url, 12][ 13, shopurl, 12][ 14, oeffnungszeiten, 12][ 15, beschreibung, 12][ 16, leistungen, 12][ 17, anfangsbuchstabe, 1][ 18, sw0, 5][ 19, sw1, 5][ 20, sw2, 5][ 21, sw3, 5][ 22, sw4, 5][ 23, sw5, 5][ 24, sw6, 5][ 25, sw7, 5][ 26, sw8, 5][ 27, sw9, 5][ 28, datenstamm, 4] In den folgenden Zeilen sind die Datensätze wie folgt definiert: [Zeilennummer, Spaltennummer, und Inhalt der Spalte] [ 0, 0, 4365][ 0, 1, Bergbau AG][ 0, 2, null][ 0, 3, Hubwagenweg 17][ 0, 4, 98765][ 0, 5, HeineHettenhausen][ 0, 6, null][ 0, 7, null][ 0, 8, +490665912345][ 0, 9, 67890][ 0, 10, null][ 0, 11, hans@wurst.de][ 0, 12, http://www.heise.de][ 0, 13, null][ 0, 14, null][ 0, 15, Mitarbeiter : 4711 / freitext : Keine hohe Akzeptanz in allgemeinen Bergbaukreisen! / kontakt : Peter Maier][ 0, 16, null][ 0, 17, null][ 0, 18, 0][ 0, 19, 0][ 0, 20, 0][ 0, 21, 0][ 0, 22, 0][ 0, 23, 0][ 0, 24, 0][ 0, 25, 0][ 0, 26, 0][ 0, 27, 0][ 0, 28, 37] [ 1, 0, 34][ 1, 1, Zillertaler Walzwerke oHG][ 1, 2, null][ 1, 3, Meiserstr. 56][ 1, 4, 3456][ 1, 5, HuhndorfMilchhausen][ 1, 6, null][ 1, 7, null][ 1, 8, +44044562353456][ 1, 9, 35623452435][ 1, 10, null][ 1, 11, hans@wurst.com][ 1, 12, http://www.web.de][ 1, 13, null][ 1, 14, null][ 1, 15, Mitarbeiter : 9 / freitext : Nur in Europa taetig. / kontakt : Klaus Topp][ 1, 16, null][ 1, 17, null][ 1, 18, 0][ 1, 19, 0][ 1, 20, 0][ 1, 21, 0][ 1, 22, 0][ 1, 23, 0][ 1, 24, 0][ 1, 25, 0][ 1, 26, 0][ 1, 27, 0][ 1, 28, 37] [ 2, 0, 567][ 2, 1, Spengler Kranarbeiten GmbH][ 2, 2, null][ 2, 3, Blechhammerweg 15][ 2, 4, 67659][ 2, 5, Kaiserslautern][ 2, 6, null][ 2, 7, null][ 2, 8, +4906313737-3][ 2, 9, null][ 2, 10, null][ 2, 11, hans@spengler.de][ 2, 12, www.spengler.de][ 2, 13, null][ 2, 28 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ 14, null][ 2, 15, Mitarbeiter : 34 / freitext : Nur in der Westpfalz bitte. / kontakt : Hans Spengler][ 2, 16, null][ 2, 17, null][ 2, 18, 0][ 2, 19, 0][ 2, 20, 0][ 2, 21, 0][ 2, 22, 0][ 2, 23, 0][ 2, 24, 0][ 2, 25, 0][ 2, 26, 0][ 2, 27, 0][ 2, 28, 37] [ 3, 0, 344][ 3, 1, Pfalztheater][ 3, 2, null][ 3, 3, WillyBrandt-Platz 4-5][ 3, 4, 67657][ 3, 5, Kaiserslautern][ 3, 6, null][ 3, 7, null][ 3, 8, +4906313675-0][ 3, 9, 3675235][ 3, 10, null][ 3, 11, info@pfalztheater.bv-pfalz.de][ 3, 12, http://www.pfalztheater.de][ 3, 13, null][ 3, 14, null][ 3, 15, Mitarbeiter : 0 / freitext : / kontakt : ][ 3, 16, null][ 3, 17, null][ 3, 18, 0][ 3, 19, 0][ 3, 20, 0][ 3, 21, 0][ 3, 22, 0][ 3, 23, 0][ 3, 24, 0][ 3, 25, 0][ 3, 26, 0][ 3, 27, 0][ 3, 28, 37] Natürlich kriegen die (neu eingefügten ) Datensätze in der internen Datenbank andere IdNummern; Beispiel: [0, 0, 14045] [1, 0, 14046] [ 2, 0, 14047] [3, 0, 14048] 5.3 Zusammenfassung: In diesem Kapitel, wurde gezeigt, wie ein Abgleich abläuft, welche Schritte dann nötig sind, und vor allem , was soll man anpassen und an welcher Stelle. Die 2 Beispiele haben dann gezeigt, dass es im grunde genommen kaum Unterschiede gibt, wo die Daten her stammen; Handelt es sich um ein File, wird es vorher angepasst, und später wie eine „richtige“ Datenbank behandelt. Das hat dazu geführt, dass man von überall seine Daten holen kann, solange die für die Klinform Firma-Datenbank relevant und wichtig sind. Im nächsten Kapitel sind dann UML-Diagramme zu den Klassen und ihren Methoden. Im letzten sind dann relevante Bücher und Links zum Thema dieser Ausarbeitung bzw. Projektarbeit 29 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ 6.Anhang Stat Comparator AbstractJob DbConnect Compare():void DoUpdateInsert():void GetrsExternDb():StaticRe cordSet GetrsExternFile()StaticRe cordSet GetrsInternDb()StaticRec ordSet Start() void getId() int doDelete() :void deleteRow() void exec() Boolean getConstraints() String getRs() Vector getStaticRecordSet()Static RecordSet getVal() String insertRow() void updateRow() void Id: int Compare() :void CopmareRows() Integer IsEqual() Boolean AutoRegister getId () int File2StaticRS GrowableArray KeyBoard SizeMax :int Data Object[] getColAmount() int getColumns() Object[] getRows() String[] LoadFile() String ElementAt() Object Insert() void Size() int DoubleSpace() void PressEnter() void ReadBooleanKeyb()Boole an ReadInt() int 30 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ StaticRecordSet startsize :int= 5000 Size :int=0 mapOrder :int[] colNames :Object[] ColTypes :int[] primaryKeys :int[] cols :int ColTypes :int[] primaryKeys :int[] cols :int getColAmount() int getColName() String getCols() int getColType() int GetDefaultMap() int[] getKey() String getPrimaryKey() int[] getRows() int getRowsAmount() int getStatus() Integer SetStatus() void Show() void ShowStatus()void GetRow() Object GetRowsForKey() int IsPrimaryKey() Boolean MapTo() int SetColName() void setElement() void 31 „KLinform: Anbindung externer Firmenstammdaten an KLinform“ 7. Literatur und links [1] Projektgruppe KLinform Klinform, Portal für die Region Kaiserslautern – Tor zum Markt der Zukunft Kaiserslautern, 2000 [2] Dietmar Abts Grundkurs Java [3] Martin Fowler, Kendall Scott UML konzentriert [4] Guido Krüger Go To Java 2 2.Auflage, Handbuch der Java-Programmierung [5] Maydene Fisher The JDBC Tutorial and Reference http://developer.java.sun.com/dvelpoers/Books/JDBCTutorial/index.html [6] JDBC-Tutorial http://www.tu-chemnitz.de/urz/java/cjug/2/ [7] Java Tutorials http://www.sun.com 32