Klassen für DB-Zugriffe
manfred miklon
- sonstiges
0 dedlfix0 manfred miklon0 manfred miklon0 dedlfix
0 dedlfix
Hallo,
habe ein Projekt, in der die Datenbankanbindung zurzeit über eine MySql-Klasse läuft. Nun soll diese wahrscheinlich bald durch eine andere Datenbank-Klasse ersetzt werden.
Doch es haben ja nicht alle die gleichen Möglichkeiten wie MySql, wie kann ich die Klasse gestalten, sodass sie damit umgehen kann?
Ich meine wie wird das in anderen Projekten mit austauschbaren Datenbank-Klassen gehandhabt? Ich meine es können ja nicht alle Klassen die selben Statements entgegennehmen?
Gruß
echo $begrüßung;
habe ein Projekt, in der die Datenbankanbindung zurzeit über eine MySql-Klasse läuft. Nun soll diese wahrscheinlich bald durch eine andere Datenbank-Klasse ersetzt werden.
Doch es haben ja nicht alle die gleichen Möglichkeiten wie MySql, wie kann ich die Klasse gestalten, sodass sie damit umgehen kann?
Du könntest dich auf das was im Allgemeinen bei allen Datenbanksystemen zur Verfügung stehende beschränken.
Ich meine wie wird das in anderen Projekten mit austauschbaren Datenbank-Klassen gehandhabt? Ich meine es können ja nicht alle Klassen die selben Statements entgegennehmen?
Aus eben diesem Grunde ist eine reine Datenbankabstraktion nur die halbe Miete. Man kann noch eine Schicht obendrauf setzen (oder beides zu einer verschmelzen), die nur noch die reinen Daten übergibt, dazu gegebenenfalls Parameter entgegennimmt. Die eigentliche Datenaufbewahrung und Beschaffung ist damit komplett verdeckt. Wenn man die bisherige Schnittstelle zur Geschäftslogik beibehält, kann man die Datenhaltung ändern, ohne dass die Anwendung davon etwas mitbekommt.
echo "$verabschiedung $name";
Hallo,
Aus eben diesem Grunde ist eine reine Datenbankabstraktion nur die halbe Miete. Man kann noch eine Schicht obendrauf setzen (oder beides zu einer verschmelzen), die nur noch die reinen Daten übergibt, dazu gegebenenfalls Parameter entgegennimmt. Die eigentliche Datenaufbewahrung und Beschaffung ist damit komplett verdeckt. Wenn man die bisherige Schnittstelle zur Geschäftslogik beibehält, kann man die Datenhaltung ändern, ohne dass die Anwendung davon etwas mitbekommt.
Danke für deine Antwort. Sprich ich übergebe keine Statements mehr an die Datenbank-Klassen sondern rufe bestimmte Methoden mit bestimmten Parmetern auf, die mir dann die Daten besorgen. Klingt gut.
Doch was mache ich z.B., wenn ich bei MySql das Datum im Statement formatiert hätte oder noch irgendeinen Join. Das ist ja nur schwer in sinnvolle Parameter etc zu packen, da fehlt mir die Idee.
zufälliges Beispiel aus dem Archiv:
SELECT * FROM table1 LEFT OUTER JOIN table2 ON table1.id=table2.old_id WHERE table2.ca_id IS NULL
Wie gestaltet man sowas sinnvoll?
Für
SELECT * FROM table1 WHERE id = 1
hätte ich z.B. an sowas gedacht $datenbank->get('*', 'table1', 'id = 1');
Das könnte ich dann intern nach Bedarf zusammenbauen.
Gruß
P.S.: Liefert mir PHP PDO nicht genau was ich brauche? Doch verstehe ich nicht genau, von was dies abhängt etc. Von der PHP-Version?
Da fällt mir gerade ArrayAccess ein, habe ich damit wohl Probleme auf gängigem Webspace der Kumpels?
echo $begrüßung;
P.S.: Liefert mir PHP PDO nicht genau was ich brauche?
Nein, PDO ist nur eine Datenbankabstraktion, keine Datenabstraktion. SDO gehet eher in die Richtung, die ich meine.
Doch verstehe ich nicht genau, von was dies abhängt etc. Von der PHP-Version?
PDO ist seit Version 5.1 Bestandteil von PHP, kann aber auhc deaktiviert werden. phpinfo() gibt Auskunft. SDO hat den Einzug ins offizielle PHP noch nicht geschafft.
Da fällt mir gerade ArrayAccess ein, habe ich damit wohl Probleme auf gängigem Webspace der Kumpels?
Das gehört zur SPL, die seit 5.0 dabei ist und ab 5.3 auch nicht mehr deaktiviert werden kann. Mit der SPL kann man Objekten einige Verhaltensweisen beibringen, die man sonst beispielsweise nur bei Arrays findet. Im Hintergrund werkeln dann Methoden, die die gewünschten Operationen mit beliebigem selbst zu schreibenden Code ausführen. Ein Array-Zugriff kann z.B. die Daten in Wirklichkeit aus einer Datenbank holen bzw. sie dort ablegen.
echo "$verabschiedung $name";
echo $begrüßung;
Doch was mache ich z.B., wenn ich bei MySql das Datum im Statement formatiert hätte oder noch irgendeinen Join. Das ist ja nur schwer in sinnvolle Parameter etc zu packen, da fehlt mir die Idee.
Es ist aus Sicht der Geschäftslogik unerheblich, ob das DBMS Joins kann oder machen muss, um an die gewünschten Daten zu kommen. Du definierst nur, wie die Schnittstellen auszusehen haben. Die Funktionen, die dir letzlich die Daten liefern sollen, können, während du die Geschäftslogik implementierst, zunächst statische Daten liefern. Wenn die Geschäftslogik fertig ist, und du weißt, welche Daten sie in welcher Form benötigt, kannst du die Datenfunktionen so umschreiben, dass sie nun echte Daten liefern, das jedoch in der gleichen Art und Weise wie die provisorischen statischen Funktionen.
Für
SELECT * FROM table1 WHERE id = 1
hätte ich z.B. an sowas gedacht $datenbank->get('*', 'table1', 'id = 1');
Das könnte ich dann intern nach Bedarf zusammenbauen.
Du hängst - zu sehen an der Verwendung des Variablennamens $datenbank - immer noch an einer bestimmten Art und Weise der Datenhaltung. Auch wie die Tabellen und Feldnamen heißen ist aus Anwendungssicht nebensächlich bis irrelevant. Wenn du Personendaten brauchst, frage nicht nach Daten aus der Tabelle Person verknüpt mit Tabelle Sowieso. Frage vielmehr nur nach der Person mit den Merkmalen X, Y und Z. Deine Datenhaltungsschicht muss daraufhin selbständig wissen, wo sie die gewünschten Informationen herzuholen hat und was sie dazu braucht.
echo "$verabschiedung $name";
Hallo,
vielen Dank für deine Antwort.
Sprich ich schiebe eine Schicht zwischen die Datenbankklassen. Diese Schicht frage ich z.B. nur nach Person xyz und dann wird jenach konfiguration die entsprechende Datenbankklasse mit den entsprechenden Statements angesprochen:
Ich brauche alle Personen, deren Geburttag (in extra tabelle) am 12.12.1999 sein soll:
$daten->hole('Person', 'Geburtstag:12.12.1999');
hole();
erkennt dann, dass Personen geholt werden sollen und überprüft die konfiguration welches Datenbanksystem verwendet wird -> MySql beispielsweise.
Also ruft hole
$mysql->query(Statement mit entsprechendem Geburtstags-Join)
auf.
Danke nochmals für deine Erläuterungen und Hilfe, vllt komme ich irgendwann noch auf den grünen Zweig.
Gruß
Hallo,
was anderes fällt mir nicht ein. Ist dies sinnvoll?
Gruß
echo $begrüßung;
was anderes fällt mir nicht ein. Ist dies sinnvoll?
Es sprach nicht mehr all zu viel dagegen, weswegen ich deine Zusammenfassung einfach so stehen ließ. Was dir sicher selbst noch auffallen wird, ist die eine generelle Methode hole(). Zur Erfüllung der meisten Aufgaben wird man nach Schema F vorgehen können. Doch irgendwann braucht es spezielle Verarbeitungsweisen. Da ist man dann besser bedient, das Generelle in einer Basisklasse abzuhandeln und das Spezielle in eigenen Klassen zu bedienen. Eine Aufteilung in eine Basisklasse und für jede Art Datenobjekt eine davon abgeleitete Klasse zu erstellen, wäre eine Lösungsmöglichkeit.
echo "$verabschiedung $name";
Hallo,
danke danke für deine Hilfe. Echt klasse!
Wenn Du von abgeleiteten Klassen für jede Art von Datenobjekt sprichst, meinst Du, dass ich eine Basisklasse habe mit dem Schema F hole(), und für alles was nicht diesem Schema F entspricht eine abgeleitete Klasse?
Komme mit den Begriffen Datenobjekt nicht ganz klar.
Des Weiteren habe ich mir gerade konkret Gedanken über die Umsetzung Schema Fs gemacht:
Klasse $datas hat die Methode hole(), die als Parameter
Was genau ist dann hier mein Datenobjekt?
Sorry, aber ich komme einfach bei der konkreten Überlegung durcheinander, wie ich das wirklcih anstellen soll.
Gruß
echo $begrüßung;
Komme mit den Begriffen Datenobjekt nicht ganz klar.
Ich dachte mir schon dass der Begriff missverständlich ist. Er ist eher allgemein zu verstehen und nicht so sehr als Objekt im OOP-Sinne. Du hast doch bestimmte Anforderungen an deine Datenhaltung. Du willst beispielsweise einmal Daten zu einer Person haben. Ein anderes Mal brauchst du ein Produkt. Und dann willst du vielleicht auch noch den Inhalt des Warenkorbs zusammen mit einigen Produkstammdaten wie Name und Preis haben.
Für die ersten beiden Datenobjekte reicht eine einfache Abfrage gegen jeweils eine Tabelle (= Schema F). Für das letzte Beispiel brauchst du einen Join aus zwei Tabellen. Hier muss die SQL-Query anders zusammengebaut werden, weswegen du die allgemeingültige hole_mir_daten_aus_einer_tabelle() nicht so verwenden kannst. Zumindest der Teil, der das Statement zusammenbaut muss überschrieben werden.
Wenn Du von abgeleiteten Klassen für jede Art von Datenobjekt sprichst, meinst Du, dass ich eine Basisklasse habe mit dem Schema F hole(), und für alles was nicht diesem Schema F entspricht eine abgeleitete Klasse?
Ich stelle mir das Ganze eher komplexer vor. Die Basisklasse kann grundsätzlich CRUD-Anfragen abfeuern und das Ergebnis abholen. Vielleicht kann sie auch beim Zusammenbau der SQL-Statements helfen. Aber sie weiß keine konkreten Namen von Tabellen oder Feldern. Diese Informationen kennen erst die davon abgeleiteten spezialisierten Klassen. Davon gibt es eine für Personen, eine für Produkte und eine für den Warenkorb. Für inhalt_mit_produktdaten() müsste die Warenkorbklasse der geerbten für den R-Teil zuständigen Methode noch beibringen, dass gejoint werden muss.
Dabei kommt man eigentlich in einen Konflikt. Für Produktdaten ist ja die Produkte-Klasse zuständig. Den Tabellen- und die Feldnamen auch in der Warenkorbklasse zu notieren heißt, diese Daten an zwei Stellen zu haben. Das ist bei einer Änderung eines Feldnamens unschön, aber in meinen Augen das kleinere Übel im Gegensatz zu den recht aufwendigen Versuchen vorhandener Implementierungen [1], dieses Problem sauber zu lösen.
[1] PEARs DB_DataObject sei mal als ein Beispiel genannt.
Sorry, aber ich komme einfach bei der konkreten Überlegung durcheinander, wie ich das wirklcih anstellen soll.
Du kannst dir ja anschauen, wie andere das Problem lösen. Es gibt diverse PHP-Frameworks, die alle das Thema Daten-Ablage angegangen sind.
echo "$verabschiedung $name";