Struktur Datenbankanwendung

Status
Nicht offen für weitere Antworten.

Marsman

Bekanntes Mitglied
Hallo!

Ich versuche, mittels einfachem Java eine kleine Datenbankanwendung zu basteln. Leider stoße ich hier immer wieder an Grenzen meines Wissens und weiß nicht so genau, wie man so etwas vernünftig aufbaut. Im Internet und in meinem Buch habe ich zwar viele Beispiele gefunden. Dieses beziehen sich aber leider immer nur auf einen Bestandteil, also nur Swing oder nur JDBC. Und wenn mal eine Beispielanwendung gezeigt wird, ist sie für einen Anfänger viel zu komplex oder enthält proprietäre Klassen. ???:L

Im folgenden, was ich bisher programmiert habe:

Die GUI ist mit Swing aufgebaut und der Datenbankzugriff erfolgt mit JDBC. In einer Tabelle werden die vorhandenen Datensätze aufgelistet. Es sollen mittels Button Datensätze hinzugefügt, geändert und gelöscht werden können. Die Eingabe der Daten erfolgt in einem separatem Fenster.

Ich lese zunächst alle Datensätze in ein Updatable Resultset. Das JTable-Model im Hauptfenster greift direkt darauf zu. Das Hinzufügen, Ändern und Löschen der Datensätze wollte ich auch direkt auf diesem Resultset durchführen. Ich hielt das so bisher für ideal, da ich nur wenig Code benötige. Ledier hat das aber drei Nachteile:

- Ein Updatable Resultset lässt sich nicht sortieren. Die "ORDER BY"-Klausel wird nicht akzeptiert.

- Bei einer großen Datei (Tabelle) ist das Scrollen in der JTable (aufgrund der vielen Zugriffe auf das Resultset) langsam.

- Und beim Hinzufügen mittels InsertRow und nachträglichem Aufruf des Datensatzes zum Ändern bekomme ich Probleme, weil die Satznummer im Resultset (GetRow()) 0 ist.



Ich erwarte nicht unbedingt eine Antwort auf diese drei Probleme. Vielmehr würde ich mich riesig freuen, wenn mir jemand ein einfaches Beispiel für eine solche "Minimalanwendung" nennen könnte. Oder einfach nur ein paar Tipps. Damit ich einen vernünftigen Einstieg habe, wie so etwas aufgebaut wird. :)


Titus
 

Caffè Latte

Bekanntes Mitglied
Hi,

du kannst den ResultSet oder Teile davon in einem Vector speichern, Dann braucht der ResultSet nicht updatable zu sein, das Scrollen sowie das Ändern und Einfügen müsste schneller sein. Die Änderungen sollten natürlich in der Datenbank wieder gespeichert werden; dabei daran denken, dass das Programm auch mal abstürzen oder sonst wie gekillt werden kann.

Nur mal so als Idee ...
 

Marsman

Bekanntes Mitglied
Hi!

Ja, ich hatte auch schon mal damit experimentiert, einen Teil der Daten in einem Vector zu cachen, um eine schnellere Anzeige der Liste zu erhalten. Und zwar die Felder, die auch in der Liste erscheinen sollen. Damit waren die anderen Probleme aber noch nicht gelöst. Und ganze Änderungen zwischenzuspeichern geht auch nicht. Denn das Prorgamm soll Multi-User-fähig sein und Änderungen müssen auch sofort für andere Benutzer sichtbar sein. Spätestens, nachdem ein anderer Benutzer seine Anzeige aktualisiert hat.

Oder habe ich deinen Vorschlag jetzt nicht richtig verstanden?


Gruß, Titus
 
S

SlaterB

Gast
gehen wir nochmal davon aus, dass 'Updatable Resultset', was immer das auch ist, nicht benutzt wird,

was ist dann das Problem? um Daten anzuzeigen muss man die einmal laden,
dann kann man sie beliebig schnell in einer JTable scrollen,
warum sollte da irgendwas langsam sein?

natürlich ist das nicht der aktuelle Stand der DB, aber den hat man ja nirgendwo,
es wäre vermessen, dein Programm live mit der Datenbank zu verbinden,
nein, es gibt höchstens einen Button 'Update', der muss dann zwar auch wieder 0.2 Sekunden Daten nachladen, aber dann ist es wieder top schnell,

speichern usw. funktioniert ganz normal mit Insert,
was genau ist nun ein Problem?
wenn Programm A was einfügt, dann kriegt Programm B das erst mit, wenn Programm B auf 'Update' klickt, das stimmt

> Und ganze Änderungen zwischenzuspeichern geht auch nicht.

macht man auch nicht, Änderungen sofort in die DB
und die eigene Tabelle natürlich entweder manuell aktualisieren,
oder besser gleich komplett neu laden, um den aktuellsten Stand zu haben
 

AlArenal

Top Contributor
SlaterB hat gesagt.:
was ist dann das Problem? um Daten anzuzeigen muss man die einmal laden,
dann kann man sie beliebig schnell in einer JTable scrollen,
warum sollte da irgendwas langsam sein?

Ist dann langsam, wenn man sich beispielsweise einfallen lässt im Model mit JDBC-Calls direkt auf der DB zu hantieren.


Was den Rest angeht: d'accord
Mie DB ist nunmal ein Datentopf und die Kommunikation erfolgt wie bei HTTP über Request-Response vom Client zum Server. Eine relationale Datenbank hat gar keine Möglichkeit Clients zu sagen "Hey, aktualisier mal deine Daten!". Dafür müsste man schon wenigstens eine 3-Tier-Anwendung schreiben mit einer serverseitigen Zwischenschicht zwischen Client und DB, die eine persistente Verbindung zum Client aufrecht erhält. Wird aber in der Regel auch nicht gemacht.
Stattdessen gibts diverse Starategien und Techniken für Caching (client-seitig) und Locking (server-/db-seitig). Da führt auch herzlich wenig dran vorbei.

Neben der Verwendung diverser Locking-Mechanismen (je nach eingesetztem RDBMS) ist es beispielsweise auch nich tunüblich jedem Datensatz von der DB einen Timestamp mit der letzten Änderung zu verpassen. Bei Schreibzugriffen muss der Client dann zunächst prüfen, ob der zu ändernde Datensatz noch vorhanden ist und ob dieser noch denselben Timestamp hat. ANdernfalls muss man die geplante Änderung verwerfen und die Daten neu laden....
 
G

Guest

Gast
SlaterB hat gesagt.:
gehen wir nochmal davon aus, dass 'Updatable Resultset', was immer das auch ist, nicht benutzt wird,

Bei einem UpdatableResultset kann man Änderungen direkt am ResultSet durchführen, die auch sofort in die DB geschrieben werden. Man spart sich dadurch weitere SQL-Statements mit INSERT, UPDATE und DELETE. Das Resultset hat selber entsprechende Methoden.

Ich fand das recht praktisch, bin dabei aber auf die von mir zuest genannten Probleme gestoßen und hatte mich (und eben hier im Forum) gefragt, ob das so überhaupt der richtige und übliche Weg ist. Deinem Beitrag nach zu urteilen wohl aber nicht. :)

Dass der Benutzer die Anzeige manchmal manuell aktualisieren muss, hatte ich mir eigentlich auch schon so gedacht. Allerdings möchte ich auch nicht nach jedem Hinzufügen eines Datensatzes in die DB die JTable neu laden müssen. Das kann bei großen Dateien zu lange dauern. Dazu nochmal eine weitere Grundsatzfrage: Wie stellt ihr die Verbindung vom JTable zur DB her? Ordnet ihr die Datensätze per RowID (rel. Satznummer) zu oder verwendet ihr immer einen Primärschlüssel?


Titus
 

AlArenal

Top Contributor
Wenn du nicht dauernd alle Daten bei Änderungen neu laden willst, musst du dir eben überlegen, wie du nur geänderte Datensätze überträgst und diese Änderungen in deine Models übernimmst, anstatt diese jedesmal komplett neu aufzubauen.
Und was die Zuordnung angeht, ist es wohl am einfachsten und naheliegendsten in den Domain-Objekten ihre ID (Primary Key) aus der DB zu verwenden.
 
G

Guest

Gast
AlArenal hat gesagt.:
Ist dann langsam, wenn man sich beispielsweise einfallen lässt im Model mit JDBC-Calls direkt auf der DB zu hantieren.

Ja, so ähnlich hatte ich das gemacht. :roll: Ich hatte beim getValueAt() des TableModels direkt auf das ResultSet zugegriffen. Leider war das viel zu langsam. Wenn ich aber die benötigten Spalten bereits beim Programmaufruf in einen Vector lade und aus diesem das JTable bediene, ist das Scrollen zwar schnell. Der Programmaufruf dauert bei mehr als 10.000 Datensätzen aber zu lange.

Stattdessen gibts diverse Starategien und Techniken für Caching (client-seitig) und Locking

Deine Tipps sind sehr interessant. Gibt es eigentlich Quellen im Internet oder Literatur, mit der man genau solche Techniken und Arbeitsweisen erlernen kann? Alle Bücher, die ich bisher gefunden habe, beschreiben entweder nur die Bereiche separat. Also Swing und JDBC getrennt von einander. Oder sie beziehen sich auf eine Entwicklungsumgebung und sind für einen Anfänger leider viel zu komplex. :?


Titus
 

AlArenal

Top Contributor
Anonymous hat gesagt.:
AlArenal hat gesagt.:
Ist dann langsam, wenn man sich beispielsweise einfallen lässt im Model mit JDBC-Calls direkt auf der DB zu hantieren.

Ja, so ähnlich hatte ich das gemacht. :roll: Ich hatte beim getValueAt() des TableModels direkt auf das ResultSet zugegriffen. Leider war das viel zu langsam. Wenn ich aber die benötigten Spalten bereits beim Programmaufruf in einen Vector lade und aus diesem das JTable bediene, ist das Scrollen zwar schnell. Der Programmaufruf dauert bei mehr als 10.000 Datensätzen aber zu lange.

Da bietet sich die Verwendung von mehreren Threads an, damit das Laden der Daten aus der DB nicht den EDT (AWT Event Dispatcher Thread) sperrt: http://www.javalobby.org/eps/galbraith-swing-2/
Ggf. reicht auch einfach die Verwendung von GlazedLists: http://www.publicobject.com/glazedlists/

Deine Tipps sind sehr interessant. Gibt es eigentlich Quellen im Internet oder Literatur, mit der man genau solche Techniken und Arbeitsweisen erlernen kann? Alle Bücher, die ich bisher gefunden habe, beschreiben entweder nur die Bereiche separat. Also Swing und JDBC getrennt von einander. Oder sie beziehen sich auf eine Entwicklungsumgebung und sind für einen Anfänger leider viel zu komplex. :?

Die diversen Locking-Mechanismen werden in der Doku des jeweiligen RDBMS behandelt. Teils, wie bei MySQL, gibts da auch beträchtliche Unterschiede in den Möglichkeiten in Abhängigkeit vom verwendeten Tabellentyp.
Ansonsten bist du einem passenden guten JDBC-Buch eigentlich schon an der richtigen Stelle, denn mit Swing hat die Synchronisation zwischen Client und Server/DB ja eigentlich nichts am Hut, denn die Probleme sind diegleichen, ob der DB-Client nun ein GUI hat oder nicht.
 

Marsman

Bekanntes Mitglied
AlArenal hat gesagt.:
Ansonsten bist du einem passenden guten JDBC-Buch eigentlich schon an der richtigen Stelle, denn mit Swing hat die Synchronisation zwischen Client und Server/DB ja eigentlich nichts am Hut, denn die Probleme sind diegleichen, ob der DB-Client nun ein GUI hat oder nicht.

Okay, das verstehe ich schon. Allerdings ist die Diskussion hier etwas von meiner ursprünglichen Frage abgekommen. Denn irgendwie benötige ich noch etwas Unterstützung bei der Erstellung eines Client-Programms mit GUI insgesamt. Ich würde es sicherlich hinbekommen, so ein Programm zu estellen. Weil ich aber grundsätzliche Fehler vermeiden möchte, wäre ein Beispiel eines solchen Programms ideal. Ich möchte quasi erlernen, wie so etwas optimal programmiert (suaberer Code etc.), besvor ich weitere Programme erstelle. Theoretosch würde schon der Source-Code zum Beispiel einer einfachen Adressenverwaltung etwa aus dem Sourcefourge-Bereich genügen. Nur erstmal finden... :bahnhof:

Gruß, Titus
 
S

SlaterB

Gast
Anonymous hat gesagt.:
SlaterB hat gesagt.:
gehen wir nochmal davon aus, dass 'Updatable Resultset', was immer das auch ist, nicht benutzt wird,

Bei einem UpdatableResultset kann man Änderungen direkt am ResultSet durchführen, die auch sofort in die DB geschrieben werden. Man spart sich dadurch weitere SQL-Statements mit INSERT, UPDATE und DELETE. Das Resultset hat selber entsprechende Methoden.

Ich fand das recht praktisch, bin dabei aber auf die von mir zuest genannten Probleme gestoßen und hatte mich (und eben hier im Forum) gefragt, ob das so überhaupt der richtige und übliche Weg ist. Deinem Beitrag nach zu urteilen wohl aber nicht. :)
klingt gar nicht schlecht so ein Updatable Resultset, dein Fehler war dann aber, das über eine Sekunde offenzuhalten,

bei allem Konfoft, welchen dieses Konstrukt bietet, sollte man doch die Grundsätze nicht außer acht lassen,
und einer ist, dass eine Verbindung aufgeht, gelesen und gerne auch geschrieben wird,
aber dann so schnell wie möglich wieder zu,
denn bevor eine Verbindung nicht geschlossen ist können z.B. andere Clienten die Änderungen auch nicht sehen,

mag sein, dass das bei Updatable Resultset nicht ganz so schlimm ist, so genau kenne ich das nicht

-----------

war jetzt nur eine verspätete Antwort, mit einem aktuell gesuchten Beispiel kann ich nicht dienen ;)
 
Status
Nicht offen für weitere Antworten.

Ähnliche Java Themen

Neue Themen


Oben