|
![]() |
|
Registriert seit: 26. Nov 2003 Ort: Halle/Saale 4.352 Beiträge Delphi 11 Alexandria |
#1
@Delbor
Ich denke, Du musst Deinen Grundsatzüberlegungen nochmal etwas ordnen und strukturieren. Nimm Dir mal ein Blatt Papier und zeichne Dir mal einen Plan, wo welche Zuständigkeiten geregelt werden sollen. Je klarer Dir das gelingt, je strukturierter wird Dein Programm aufgebaut sein. Für Außenstehende ist vermutlich schwer nachzuvollziehen, was Du aktuell genau vorliegen hast und was Du ändern willst. Z.B. ist m.E. bisher nicht klar geworden, wie diese Komponenten
Delphi-Quellcode:
aufgebaut sind. Haben sie noch eine Verbindung zur Datenbank oder nicht?
FTblBildText : TTblBildText; // FBildDescribeTabelle : TBildDescribeTabelle;
FTblAlbum : TTbl_Album; // FKategoryTabelle : TKategoryTabelle; Wenn nicht, warum sind es dann unterschiedliche Klassen und warum sind die Felder unterschiedlich benannt? Wenn ja, warum nimmst Du nicht eine Klasse, die die Daten unabhängig von einer Datenbank verwaltet und bearbeitet? Wie viele Daten verwaltest Du insgesamt in der Anwendung? Können alle Daten insgesamt im Speicher gehalten werden oder ist die Datenbank so groß, dass immer nur bestimmte Datensätze daraus abgeholt werden können? Das sind viele grundsätzliche Fragen, die eigentlich erst mal geklärt werden müssten und zu entsprechend unterschiedlichen Lösungen führen werden. Wie in #12 schon mal angesprochen, musst Du Dir eine übersichtliche Struktur überlegen, die klare Zuständigkeiten und Verbindungen verschiedener Projektmodule abbildet. Dafür gibt es dann je nach den Gegebenheiten verschiedene Lösungsmöglichkeiten. Was ich generell nicht verstehe ist, dass Du Deine Businessklassenstruktur änderst, wenn Du die Datenbank wechselst oder die Tabellen in der Datenbank andere Namen haben. Nach meiner Überlegung müsstest Du in Deinem Projekt das "Datenbankmodul" anpassen, aber nicht die Businessklassen. Interfaces zu verwenden kann sinnvoll sein, muss es aber nicht in jedem Fall. Wenn Du damit noch keine Erfahrungen hast, würde ich die Projektstruktur erst mal überarbeiten und auf Interfaces verzichten. Da hängt noch einiges an notwendigen Anpassungen dran, die jetzt vielleicht unnötig verwirren würden. Statt dessen solltest Du eine Datenbankunit oder Datenbankklasse einführen, die alle Zugriffe auf die alte Datenbank kapselt - so dass Deine Anwendung nicht mehr die Datenbank selbst kennt, sondern nur noch Deine Datenbankunit oder Datenbankklasse. Dann kannst Du eine neue Datenbankunit oder -Klasse aufbauen, die die selben Schnittstellen nach außen hat, aber intern auf eine andere Datenbank geht. So hättest Du schon mal eine gute Trennung der Zuständigkeiten.
Stahli
![]() --- "Jetzt muss ich seh´n, dass ich kein Denkfehler mach...!?" Dittsche (2004) |
![]() |
Registriert seit: 8. Okt 2006 Ort: St.Gallen/Schweiz 1.192 Beiträge Delphi 11 Alexandria |
#2
Hi zusammen
@ stahli ![]() FTblBildText : TTblBildText; // FBildDescribeTabelle : TBildDescribeTabelle;
FTblAlbum : TTbl_Album; // FKategoryTabelle : TKategoryTabelle; Die Datenbank selbst beinhaltet 12 Tabellen, wovon zurzeit nur 4 für Bild- und Textinhalte zuständig sind. Von drei dieser Tabellen gibt es innerhalb von TQueryresultClass Entsprechungen gleichnamiger Klassen. Das obige Zitat gibt 2 Klassenfelder meiner gleichaufgebauten Klassen TQueryCMresultClass(FTblBildText ,FTblAlbum) und TQueryresultClass(FBildDescribeTabelle,FKategoryTa belle) wider. Ich hänge hier mal noch TQueryCMresultClass an, um die Unterschiede zu verdeutlichen; diese bestehen ausschlieslich aus den in TQueryCMresultClass verwendeten kürzeren Tabellen- und Feldbezeichnern. Natürlich wurde die SQLite_Datenbank auch mit den verkürzten Tabellennamen erstellt. ![]() Haben sie noch eine Verbindung zur Datenbank oder nicht?
Bei Select-Abfragen der TQuery-Komponente werden deren Resultate jeweils pro Datensatz über 3 Tabellen (ohne Zwischentabelle) in einer TQueryCMresultClass - Instanz festgehalten und diese einer Objectlist hinzugefügt. Dabei gibt es eine Besonderheit: Bilddaten werden bei der ursprünglichen Abfrage über mehrere Datensätze mit Ausnahme des Thumbnails vorerst nicht abgefragt, sondern erst, wenn sie zur Darstellung des Bildes benötigt werden. Ein Ziel meiner Umstellung auf SQLite: von mir so genannte "Satelliten-DBs" zu erstellen(*). Das hat folgende Grund: Zur Zeit speichere ich die Bilder noch in einem Ordner auf Festplatte. Wenn die Dinger schliesslich in die DB geschrieben werden, werden aus den Rohbildern nicht nur die Thumbnails, sondern auch gleichzeitig Bitmaps in Originalgrösse erstellt. Dabei sollten auch die Rohdaten ursprünglich mit in die DB - und blähen diese zu gigantischer Grösse auf. Und hier kommen dann meine "Satelliten-DBs" zum Zug: In ihnen werden die Rohdaten und Originalbitmaps zusammen mit einem Textfeld für den Namen und einem FK-Integer für das Album gespeichert. Diese Dinger bringen es auf Grössen von in etwa 25GB oder weniger, sind also eigentlich sogar als eine Art Rohdatenbackup zu gebrauchen und können Extern an beliebigen Orten gespeichert werden. Wo sich diese "Satelliten-DBs" befinden, bestimmt letzlich der User über ein Optionen-Fenster. ![]() Wie viele Daten verwaltest Du insgesamt in der Anwendung? Können alle Daten insgesamt im Speicher gehalten werden oder ist die Datenbank so groß, dass immer nur bestimmte Datensätze daraus abgeholt werden können?
![]() Was ich generell nicht verstehe ist, dass Du Deine Businessklassenstruktur änderst, wenn Du die Datenbank wechselst oder die Tabellen in der Datenbank andere Namen haben.
Delphi-Quellcode:
Das dürfte viel schwerer zu lesen sein als:
function TFDMySQLDml.DefineBildSQL3(Kath_Id: Integer) : String;
begin Result := 'SELECT Bildtabelle.idBild as BildID, ' + 'bilddescribetabelle.BilddesribeID as BildDescribeId, ' + 'bilddescribetabelle.bildkatID as BildkatID, '+ 'bilddescribetabelle.bildname as Bildname, ' + 'bilddescribetabelle.bildbeschreibung as Bildbeschreibung, '+ 'bilddescribetabelle.bildlegende as bildlegende, ' + 'kategorien_tabelle.Kath_ID as KathID, ' + 'kategorien_tabelle.Kategorie as Kategorie, '+ 'kategorien_tabelle_has_bilddescribetabelle.kategorien_tabelle_Kath_ID as TblKat_Id, '+ 'kategorien_tabelle_has_bilddescribetabelle.BildDescribeTabelle_BilddesribeID as BildDesc_Id '+ 'FROM ' + 'bildtabelle, bilddescribetabelle, ' + 'kategorien_tabelle_has_bilddescribetabelle, ' + 'kategorien_tabelle '+ 'WHERE '+ {erste Tabelle} 'Kategorien_tabelle.Kath_Id = :Kath_Id '+ 'AND '+ {zweite (Selektionstabelle) Tabelle wird mit erster verglichen} 'kategorien_tabelle_has_bilddescribetabelle.kategorien_tabelle_Kath_ID = Kategorien_tabelle.Kath_Id ' + 'AND '+ //-------------------- 'kategorien_tabelle_has_bilddescribetabelle.BildDescribeTabelle_BilddesribeID = bilddescribetabelle.BilddesribeID ' + 'AND '+ 'Bildtabelle.idBild = bilddescribetabelle.bildtabelle_idbild'; // Showmessage(Result); end;
Delphi-Quellcode:
Wobei ich jetzt nur mal einiges ersetzen lassen habe - zu Demozwecken in einer neuangelegten, aber nicht gespeicherten Unit.
function TFDMySQLDml.DefineBildSQL3(Kath_Id: Integer) : String;
begin Result := 'SELECT Tbl_Bild.idBild as BildID, ' + 'TblBildText.BilddesribeID as BildDescribeId, ' + 'TblBildText.bildkatID as BildkatID, '+ 'TblBildText.bildname as Bildname, ' + 'TblBildText.bildbeschreibung as Bildbeschreibung, '+ 'TblBildText.bildlegende as bildlegende, ' + 'TblAlbum.Kath_ID as AlbumId, ' + 'TblAlbum.Kategorie as Kategorie, '+ 'TblAlbum_has_TblBildText.TblAlbum_Album_Id as TblKat_Id, '+ 'TblAlbum_has_TblBildText.TblBildText_BilddesribeID as BildDesc_Id '+ 'FROM ' + 'bildtabelle, TblBildText, ' + 'TblAlbum_has_TblBildText, ' + 'TblAlbum '+ 'WHERE '+ {erste Tabelle} 'TblAlbum.Album_Id = :Album_Id '+ 'AND '+ {zweite (Selektionstabelle) Tabelle wird mit erster verglichen} 'TblAlbum_has_TblBildText.TblAlbum_Album_Id = TblAlbum.Album_Id ' + 'AND '+ //-------------------- 'TblAlbum_has_TblBildText.TblBildText_BilddesribeID = TblBildText.BilddesribeID ' + 'AND '+ 'Bildtabelle.idBild = TblBildText.bildtabelle_idbild'; // Showmessage(Result); end; ![]() Nach meiner Überlegung müsstest Du in Deinem Projekt das "Datenbankmodul" anpassen, aber nicht die Businessklassen.
![]() Interfaces zu verwenden kann sinnvoll sein, muss es aber nicht in jedem Fall. Wenn Du damit noch keine Erfahrungen hast, würde ich die Projektstruktur erst mal überarbeiten und auf Interfaces verzichten. Da hängt noch einiges an notwendigen Anpassungen dran, die jetzt vielleicht unnötig verwirren würden.
Für Interfaces gibts erstmal ein (umfangreiches?) Testprogramm. Und erst Sachen, die da funktionieren und mir klar ist, warum sie das tun, können in meinem Programm eingebaut werden. ![]() Statt dessen solltest Du eine Datenbankunit oder Datenbankklasse einführen, die alle Zugriffe auf die alte Datenbank kapselt - so dass Deine Anwendung nicht mehr die Datenbank selbst kennt, sondern nur noch Deine Datenbankunit oder Datenbankklasse.
Dann kannst Du eine neue Datenbankunit oder -Klasse aufbauen, die die selben Schnittstellen nach außen hat, aber intern auf eine andere Datenbank geht. (*) abgesehen davon, dass es eigentlich unsinnig ist, als Anwendungsdatenbank einen Server wie MySQL zu verwenden (Ausnahme:EmbeddedServer) Gruss Delbor
Roger
Man muss und kann nicht alles wissen - man muss nur wissen, wo es steht. Frei nach Albert Einstein ![]() |
![]() |
Ansicht |
![]() |
![]() |
![]() |
ForumregelnEs ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.
BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus. Trackbacks are an
Pingbacks are an
Refbacks are aus
|
|
Nützliche Links |
Heutige Beiträge |
Sitemap |
Suchen |
Code-Library |
Wer ist online |
Alle Foren als gelesen markieren |
Gehe zu... |
LinkBack |
![]() |
![]() |