Entwerfen von DTOs mit Fremdschlüsselbeziehungen

8

Ich verwende Java + Spring Framework für eine Web-Anwendung. Ich benutze kein ORM-Tool. Stattdessen versuche ich, die DB-Beziehungen als Java-Objekte mit einfachen DAO / DTO-Muster zu modellieren. Wenn der DTO genau einer einzelnen Tabelle in der Datenbank entspricht, ist dies sehr einfach. Wenn es jedoch Tabellen gibt, die sich auf andere Tabellen beziehen, die Fremdschlüssel verwenden, bin ich nicht sicher, was der beste Ansatz dafür ist. Sah in Stackoverflow nach ähnlichen Antworten, konnte aber keine für meine Bedürfnisse finden. Ich möchte ein sehr spezifisches Beispiel geben. Angenommen, es gibt zwei Entitäten Benutzer und Gruppe. Ich habe ein Benutzer-DTO und ein Gruppen-DTO, jeweils mit UserDao (JdbcUserDao) und GroupDao (JdbcGroupDao).

Jetzt habe ich eine Beziehung in der DB, die den Benutzer und die Gruppe verbindet. Ein Benutzer kann mehreren Gruppen angehören. Der Tabellenname ist User_Group_Association mit der folgenden DB-Definition:

Benutzer-ID | group_id

Hier ist user_id ein Fremdschlüssel, der sich auf die Benutzertabelle bezieht. Ähnlich bezieht sich group_id auf eine Gruppentabelle. Wenn ich dieses DTO in Java modelliere, sollte ich Folgendes tun:

%Vor%

ODER sollte es so sein:

%Vor%

Besonderer UI-Anwendungsfall: Ich möchte Benutzernamen und die zugehörigen Gruppennamen anzeigen, denen sie angehören. So etwas -

Name - & gt; Gruppennamen

Keshav - & gt; Admin, EndUser, ReportAdmin
Kiran - & gt; BerichtAdmin
Pranav - & gt; Endbenutzer

Beim ersten Ansatz zum DTO-Design muss ich die Benutzerdetails (Namen) und Gruppendetails (Namen) erneut aus der Datenbank holen. Bei der zweiten Methode müsste ich die Benutzer- und Gruppenobjekte abrufen, wenn ich das UserGroupAssoc-Objekt selbst erstelle.

In einem dritten Ansatz kann ich den UserGroupAssoc DTO wie folgt entwerfen:

%Vor%

In diesem dritten Ansatz schließe ich Tabellen in SQL an, um nur die benötigten Felder für den Anwendungsfall zu erhalten, und modelliere dann den DTO entsprechend.

Welches ist der Standardansatz, um dieses Szenario zu erreichen? Sind Tische im DTO Design in Ordnung? Einige haben die Meinung, dass ein DTO nur einer Tabelle entsprechen sollte und die zugehörigen Objekte in der App-Ebene aggregiert sein sollten. Das hat den Overhead, mehrere Objektabrufe von DB zu machen, richtig? Zu verwirrt über die richtige Vorgehensweise, Entschuldigung für eine so lange Erklärung!

    
Keshav 07.01.2012, 12:15
quelle

1 Antwort

6

Disclaimer: Ich bin kein ORM-Spezialist ...

... aber in einem klassischen Viele-zu-viele-Beziehungen , das Sie nicht tun brauche nicht das dritte Datenmodell ( UserGroupAssoc ). Die Klasse User enthält eine Sammlung von Group s:

%Vor%

Wenn Sie auch die umgekehrte Beziehung benötigen (eine Gruppe enthält Benutzer), sieht die Klasse Group wie folgt aus:

%Vor%

Und wieder, die klassische Art, dies zu tun, ist die Verwendung von "Domänenobjekten" (DTOs) in der Sammlung ( User und Group anstelle von userId und groupId ).

Normalerweise brauchen Sie ein drittes Domänenobjekt nur, wenn die Assoziationstabelle ( User_Group_Association ) etwas anderes als user_id und group_id enthält (vielleicht einen Autorisierungscode, der es einem Benutzer erlaubt, der Gruppe hinzugefügt zu werden, was auch immer):

%Vor%

In diesem Fall könnte die Klasse UserGroupAssoc diese Struktur haben:

%Vor%

Und die Viele-zu-Viele-Beziehung zwischen User und Group wird in zwei Viele-zu-Eins-Beziehungen mit diesem neuen Domänenobjekt umgewandelt. Normalerweise werden die Domänenobjekte bevorzugt verwendet ( User und Group anstelle von userId und groupId ).

  

Welches ist der Standardansatz, um dieses Szenario zu erreichen?

Nun, wenn Sie ein ORM-Framework verwenden würden, wäre dies die Standardmethode, mit der das Framework es getan hat. Aber da Sie eine benutzerdefinierte ORM-Lösung haben, ist es schwer zu sagen.

  

Ist die Verknüpfung von Tabellen im DTO-Design in Ordnung?

Warum sollte das DTO-Design in der Anwendungsschicht durch die Verknüpfung von Tabellen in der Datenbank beeinflusst werden? Dies ist ein Fall für die objektrelationale Impedanzabweichung und vielleicht auch für die Gesetz der undichten Abstraktion , da Sie die relationale Domäne nicht vollständig in eine Objektdomäne abstrahieren können, die eine 1: 1-Entsprechung beibehält.

  

Einige haben die Meinung, dass ein DTO nur einer Tabelle entsprechen sollte und die zugehörigen Objekte in der App-Ebene aggregiert sein sollten. Das hat den Overhead, mehrere Objektabrufe von DB zu machen, richtig?

ORM hat einige Einschränkungen (siehe auch die objektrelationale Impedanzfehlanpassung für einige Probleme, mit denen Sie möglicherweise konfrontiert werden), und es ist schwierig, Ihre Domänenobjekte so zu modellieren, dass sie den Einschränkungen der relationalen Datenbank entsprechen oder umgekehrt. Berichte sind ein gutes Beispiel in dieser Richtung.

Ein Bericht fasst normalerweise Daten aus mehreren Tabellen zusammen. Dies ist natürlich kein Problem für einige SQL-Joins, aber wie werden Sie das Ergebnis DTOs zuordnen? Wie du es selbst gesagt hast ...

  

Wenn der DTO genau einer einzelnen Tabelle in der Datenbank entspricht, ist das sehr einfach

... aber das Berichtsergebnis wird nicht einer einzelnen Tabelle zugeordnet, es muss auf Fragmente aus mehreren Tabellen abgebildet werden.

Je nachdem, welche Anforderungen Sie in der Anwendung haben, könnten Sie am Ende einige komisch aussehende Klassen oder unpassend aussehende SQL-Anweisungen erhalten. Möglicherweise führen Sie am Ende mehr Abfragen als benötigt, um die richtigen Objektmodelle und Verknüpfungen zwischen ihnen zu erhalten; oder Sie haben möglicherweise ähnliche DTOs, nur um die Anzahl der Fahrten zur Datenbank zu begrenzen und eine bessere Leistung zu erzielen.

Also versuche ich zu sagen (wieder der Disclaimer, dass ich kein ORM-Spezialist bin), dass nicht alle Anwendungen ein guter Kandidat für ORM sind; Aber wenn Sie überlegen, weiterzumachen, schauen Sie sich vielleicht an, wie Hibernate / JPA die Probleme anspricht, oder gehen Sie sogar voran und verwenden Sie sie stattdessen.

    
Bogdan 08.01.2012, 11:41
quelle

Tags und Links