Ich habe eine Tabelle namens Cat
und eine PHP-Klasse namens Cat
. Jetzt möchte ich eine CatDataMapper
-Klasse machen, also Cat extends CatDataMapper
.
Ich möchte, dass diese Data-Mapper-Klasse grundlegende Funktionen zum Ausführen von ORM und zum Erstellen, Bearbeiten und Löschen von Cat.
bereitstelltZu diesem Zweck könnte vielleicht jemand, der dieses Muster sehr gut kennt, mir hilfreiche Ratschläge geben? Ich denke, es wäre ein bisschen zu einfach, nur einige Funktionen wie update (), delete (), save () bereitzustellen.
Ich stelle fest, dass ein Data Mapper dieses Problem hat: Zuerst erstellst du die Instanz von Cat und initialisierst dann alle Variablen wie name, furColor, eyeColor, purrSound, meowSound, Begleiter usw .. und nachdem alles eingerichtet ist, rufst du an die Funktion save (), die von CatDataMapper übernommen wird. Das war einfach;) Aber jetzt, das eigentliche Problem: Sie fragen die Datenbank nach Katzen ab und erhalten ein einfaches langweiliges Ergebnis mit vielen Katzendaten.
PDO bietet einige ORM-Funktionen zum Erstellen von Cat-Instanzen. Nehmen wir an, ich benutze das, oder sagen wir sogar, ich habe eine mapDataset () -Funktion, die ein assoziatives Array nimmt. Sobald ich jedoch mein Cat-Objekt aus einem Datensatz habe, habe ich redundante Daten. Zur gleichen Zeit könnten zwanzig Benutzer die gleichen Katzendaten von der Datenbank aufnehmen und das Katzobjekt editieren, d. H. Die Katze umbenennen und speichern (), während ein anderer Benutzer noch etwas über das Setzen einer anderen Pelzfarbe tut. Wenn alle ihre Änderungen speichern, ist alles durcheinander.
Ähm ... ok, um diese Frage wirklich kurz zu halten: Was ist eine gute Übung hier?
Der Data Mapper ist eine Softwareschicht das trennt die speicherinternen Objekte aus der Datenbank. Seine Verantwortung ist es, Daten zwischen den beiden zu übertragen und sie auch von jedem zu isolieren andere. Mit Data Mapper den In-Memory Objekte müssen nicht einmal wissen, dass es da ist eine vorhandene Datenbank; Sie brauchen kein SQL Schnittstellenkode und sicherlich nein Kenntnis des Datenbankschemas. (Das Datenbankschema ist immer unwissend die Objekte, die es verwenden.) Da es ein ist Form von Mapper (473), Data Mapper selbst ist der Domäne unbekannt Ebene.
Daher sollte ein Cat CatDataMapper nicht erweitern, da dies eine is-a-Beziehung erzeugen und die Cat-Bindung an die Persistence-Ebene binden würde. Wenn Sie in der Lage sein möchten, die Persistenz Ihrer Katzen auf diese Weise zu behandeln, sehen Sie sich ActiveRecord oder eine der anderen Datenquellen an Architekturmuster.
Wenn Sie ein Domänenmodell verwenden, verwenden Sie normalerweise einen DataMapper. Ein einfacher DataMapper würde einfach eine Datenbanktabelle einer äquivalenten In-Memory-Klasse auf Feld-zu-Feld-Basis zuordnen. Wenn jedoch ein DataMapper benötigt wird, haben Sie normalerweise keine so einfachen Beziehungen. Tabellen werden Ihren Objekten nicht 1: 1 zugeordnet. Stattdessen könnten mehrere Tabellen zu einem Objekt-Aggregat und umgekehrt zusammengefasst werden. Folglich kann die Implementierung von nur CRUD-Methoden leicht zu einer Herausforderung werden.
Abgesehen davon handelt es sich um eines der komplizierteren Muster (umfasst 15 Seiten in PoEA), die oft in Kombination mit dem Repository verwendet werden Muster unter anderem. Suchen Sie in der Spalte Verwandte Fragen auf der rechten Seite dieser Seite nach ähnlichen Fragen.
Was Ihre Frage zu mehreren Benutzern betrifft, die dieselbe Katze bearbeiten, ist dies ein häufiges Problem, das Parallelität genannt wird. Eine Lösung wäre, die Zeile zu sperren , während jemand sie bearbeitet. Aber wie alles kann zu anderen Problemen führen .
Wenn Sie sich auf ORMs wie Doktrin oder
Der Hydrationsprozess ist der Prozess der Umwandlung eines "einfachen langweiligen" MySQL-Ergebnissatzes in nette Objekte mit Gettern und Setter. Für einen Abruf würden Sie also etwas wie Die Einfügung wäre so einfach wie das: CatPeer::doSelect()
verwenden. Dann für ein neues Objekt würden Sie es zuerst instanziieren (oder abrufen und Instanz von der DB):
$cat = new Cat();
$cat->save();
Das wäre äquivalent zu einer Einfügung (oder einer Aktualisierung, wenn das Objekt bereits in der Datenbank existiert ... Das ORM sollte wissen, wie man den Unterschied zwischen neu und existierende Objekte, indem beispielsweise das Vorhandensein oder Fehlen eines Primärschlüssels verwendet wird).
Die Implementierung eines Data Mappers ist in PHP & lt; 5.3, da Sie geschützte / private Felder nicht lesen / schreiben können. Beim Laden und Speichern der Objekte haben Sie einige Möglichkeiten:
Die erste Methode hat die Möglichkeit, mit einer neuen Version zu brechen, und ist sehr grob, die zweite ist eine (sehr) schlechte Praxis.
Die dritte Option wird ebenfalls als schlechte Methode betrachtet, da Sie keine Getter / Setter für alle Ihre Felder bereitstellen sollten, nur diejenigen, die sie benötigen. Ihr Modell wird von einer reinen DDD-Perspektive (domain driven design) "beschädigt", da es Methoden enthält, die nur aufgrund des Persistenzmechanismus benötigt werden. Es bedeutet auch, dass Sie jetzt ein anderes Mapping für die Felder beschreiben müssen - & gt; Setter-Methoden, neben den Feldern - & gt; Tabellenspalten.
PHP 5.3 bietet die Möglichkeit, auf alle Arten von Feldern zuzugreifen und diese zu ändern, indem man reflection verwendet:
Damit können Sie einen echten Data Mapper erreichen, da die Notwendigkeit, Mutatoren für alle Felder bereitzustellen, aufgehört hat.
PDO bietet einige ORM-Funktionen für Erstellen Sie Cat-Instanzen. Sagen wir, ich benutze das, oder sagen wir mal, ich habe eine Funktion mapDataset (), die ein assoziatives Array. Aber sobald Ich habe mein Cat-Objekt aus einem Datensatz, ich habe redundante Daten. Gleichzeitig, zwanzig Benutzer könnten das gleiche aufheben Katzendaten aus der Datenbank und bearbeiten das Katzenobjekt, d. h. die Katze umbenennen, und speichern () es, während ein anderer Benutzer noch Dinge über das Setzen eines anderen Pelzfarbe. Wenn alle ihre retten Bearbeitungen, alles ist durcheinander.
Um den Status der Daten in der Regel zu verfolgen und IdentityMap und / oder ein UnitOfWork zu verwenden, sollten Sie alle verschiedenen Operationen auf abgebildeten Entitäten verfolgen ... und das Ende des Anforderungszyklus al die Operationen wären durchgeführt.
Tags und Links php orm datamapper