Umgang mit Beziehungen zum Data-Mapper-Muster

9

Ich verwende das Data-Mapper-Muster und frage mich, wie man die Beziehungen zu diesem Muster am besten handhaben kann. Ich habe viel Zeit damit verbracht, nach Lösungen in Google und Stack zu suchen. Ich habe einige gefunden, aber ich bin immer noch nicht ganz glücklich darüber, besonders in einem speziellen Fall, den ich versuchen werde zu erklären.

Ich arbeite mit PHP, also sind die Beispiele für Code, die ich verwenden werde, in PHP.

Nehmen wir an, ich habe eine Tabelle "team" (ID, Name) und eine Tabelle "player" (id, name, team_id). Dies ist eine 1-N-Beziehung. Durch die Implementierung des Data Mapper-Patterns werden wir die folgenden Klassen haben: Team, TeamMapper, Player und PlayerMapper.

Bisher ist alles einfach. Was, wenn wir alle Spieler aus einem Team holen wollen?

Die erste Lösung, die ich gefunden habe, ist eine Methode getAllPlayers () in der Team-Klasse zu erstellen, die das mit Lazy Loading und Proxies behandelt. Dann können wir die Spieler eines Teams wie folgt abrufen:

%Vor%

Die zweite Lösung, die ich gefunden habe, besteht darin, den PlayerMapper direkt zu verwenden und die Team-ID als Parameter zu übergeben. Etwas wie:

%Vor%

Nun möchte ich sagen, dass ich eine HTML-Tabelle mit allen Teams und mit einer Spalte "Spieler" mit allen Spielern eines jeden Teams anzeigen möchte. Wenn wir die erste Lösung verwenden, die ich beschrieben habe, müssen wir eine SQL-Abfrage durchführen, um die Liste der Teams und eine Abfrage für jedes Team zu erhalten, was N + 1 SQL-Abfragen bedeutet, wobei N die Anzahl der Teams ist / p>

Wenn wir die beschriebenen zweiten Lösungen verwenden, können wir zuerst alle Team-IDs abrufen, sie in ein Array einfügen und sie dann an die findAll-Methode des Player-Mappers übergeben, etwa so:

%Vor%

In diesem Fall müssen wir nur 2 Abfragen ausführen. Viel besser. Aber ich bin immer noch nicht sehr glücklich mit dieser Lösung, weil die Beziehungen nicht in den Modellen beschrieben werden und es der Entwickler ist, der über sie Bescheid wissen muss.

Also meine Frage ist: Gibt es andere Alternativen mit dem Data Mapper-Muster? Mit dem Beispiel, das ich gab, gibt es eine gute Möglichkeit, alle Teams mit allen Spielern in nur 2 Abfragen mit der Beschreibung der Beziehungen in das Modell auszuwählen?

Vielen Dank im Voraus!

    
Vincent 05.12.2012, 13:58
quelle

2 Antworten

2

Wenn Sie sich den Text von Martin Fowler ansehen, der beschreibt, wie der DataMapper funktioniert, können Sie eine Abfrage verwenden, um alle benötigten Daten zu erhalten und diese Daten an jeden Mapper weiterzuleiten, damit der Mapper sie auswählen kann nur die Daten, die es braucht.

Für Sie wäre dies eine Abfrage, die sich von Team zu Player verbindet und ein Resultset mit doppelten Team-Daten für jeden einzelnen Player zurückgibt.

Sie müssen dann die Duplizierung in Ihrem Mapping-Code berücksichtigen, indem Sie nur neue Objekte erstellen, wenn sich die Daten ändern.

Ich habe etwas Ähnliches getan, bei dem der Team Mapper über die Ergebnismenge iteriert und für jedes eindeutige Team die Ergebnismenge an den Player Mapper weitergibt, so dass er einen Spieler erstellen und den Spieler dann zum Spieler hinzufügen kann Team-Sammlung.

Während das funktioniert, gibt es Probleme mit diesem Ansatz weiter stromabwärts ...

    
David Osborne 05.12.2012 16:43
quelle
0

Ich habe eine mögliche Lösung für dieses Problem, das ich in einem meiner Projekte erfolgreich umgesetzt habe. Es ist nicht so komplex und würde in dem oben beschriebenen Beispiel nur 2 Abfragen verwenden.

Die Lösung besteht darin, eine weitere Codeebene hinzuzufügen, die für die Verarbeitung von Beziehungen zuständig ist.

Zum Beispiel können wir das in eine Serviceklasse einfügen (die auch für andere Dinge verwendet werden kann, nicht nur für die Handhabung von Beziehungen). Nehmen wir an, wir haben einen Klassen-TeamService über Team und TeamMapper. TeamService würde eine Methode getTeamsWithRelationships () haben, die ein Array von Team-Objekten zurückgeben würde. getTeamsWithRelationships () würde TeamMapper verwenden, um die Liste der Teams zu erhalten. Dann würde es mit dem PlayerMapper nur eine Abfrage der Liste der Spieler für diese Teams geben und die Spieler den Teams zuweisen, indem eine setPlayers () -Methode aus der Team-Klasse verwendet wird.

Diese Lösung ist ziemlich einfach und leicht zu implementieren und funktioniert gut für alle Arten von Datenbankbeziehungen. Ich nehme an, dass einige Leute etwas dagegen haben. Wenn ja, würde mich interessieren, was die Probleme sind?

    
Vincent 12.08.2015 09:45
quelle