Hibernate Self Melden Sie sich
Frage
Hintergrund
Ich habe eine Tabelle mit Spalten ID, ImageId, PropertyId.
Es könnte viele Bilder geben, die mit einer einzelnen Eigenschaft verbunden sind, und es könnte viele Eigenschaften geben, die mit einem einzelnen Bild verbunden sind.
imageId - many-to-many - propertyId
Ich habe eine Liste von PropertyIDs und möchte alle Bilder finden, die mit allen PropertyIDs verknüpft sind Hibernate verwenden.
Problem.
Gerade jetzt wähle ich jeweils eine Eigenschaft aus und benutze die Kriterien -API. Finden Sie alle im ImageIDs zugeordneten ImageIDs, die ich eine Liste von ImageIDs erhalte. Ich verwende diese Liste von ImageIDs in der nächsten Abfrage und sage
select imageIds where imageId in (imageIds obtained in previous step) where propertyId = x
So effektiv würde die Anzahl der Abfragen, die auf die DB auftreten, der Anzahl der Eigenschaften entsprechen. Ich denke nicht, dass dies eine gute Lösung ist. Ich muss die Datenbank n -mal treffen. Ich habe versucht, eine abgetrennte Abfrage zu verwenden, aber es war nicht erfolgreich. Gibt es eine bessere Lösung?
Wenn ich endlich die Liste der ImageIds erhalte, ist es auch eine gute Idee (berücksichtigen wir nicht die Anzahl der Ergebnisse), um sie in der Benutzersitzung zu speichern und zu paginieren, oder ist es eine gute Idee, den gesamten Vorgang zu wiederholen oder soll Ich erwähne es, es für den Zweck der Pagination in der DB zu speichern?
Lösung
Hier ist ein Problem mit Ihrem Datenbankschema:
Sie versuchen, 3 separate Assoziationen (Bild - Sammlung, Bild - Eigenschaft, Sammlung - Eigenschaft) in eine einzelne ImageCollection Tisch. Das ist keine gute Sache. Während Sie wahrscheinlich mit einfachem SQL davonkommen könnten (zu vielen Zeilen mit Nullspalten in dieser Tabelle), können Sie dies nicht in Hibernate ordnungsgemäß zuordnen. Übrigens benötigt diese Tabelle keinen Ersatz -Primärschlüssel.
Was Sie tun müssen, ist es in 3 separate Tabellen aufzuteilen und Ihr Modell in Winterschlafnatur als richtig viel zu viel zu haben. Zum Beispiel:
@Entity
public class Image {
@ManyToMany
@JoinTable(
name="IMAGE_PROPERTIES",
joinColumns=@JoinColumn(name="IMAGE_ID"),
inverseJoinColumns=@JoinColumn(name="PROPERTY_ID")
)
private Collection<Property> properties;
...
}
IMAGE_PROPERTIES
Tabelle wird nur haben IMAGE_ID
und PROPERTY_ID
Säulen; du wirst haben COLLECTION_IMAGES
und COLLECTION_PROPERTIES
Tische wie es auch.
Sie können dann Bilder nach Eigenschaftsnamen wie folgt abfragen.
from Image img
left join img.properties as prop
with prop.name in ('Tag1', 'Tag2', 'Tag3')
Wenn Ihre Eigenschaften wirklich wie Tags sind, werfen Sie einen Blick auf Dieser Artikel für und / oder / Union -Abfrage Beispiele.
Wenn Ihre Eigenschaften wirklich Eigenschaften sind (das heißt, sie haben den Lebenszyklus der Eigentümereinheit und können nicht mehr als einer Entität gleichzeitig angehören), sollten Sie sie in zwei Tabellen (eine für Bilder und eine für Sammlungen) aufzeigen und eins zu verwenden. To-Viele Assoziationen. Auf diese Weise werden Sie nicht brauchen IMAGE_PROPERTIES
und COLLECTION_PROPERTIES
Tische von oben.
Andere Tipps
Sie haben also eine solche Klasse (Hinweis: Ich habe dies nicht mit einer IDE geschrieben, daher ist der Code möglicherweise nicht syntaktisch korrekt):
public class Property {
@ManyToMany
private List<Image> images;
}
public class Image {
@ManyToMany
private List<Property> properties;
}
Also eine Frage wie select property from Property property
Sollten Sie die Liste der Eigenschaften erhalten, auf die Sie durch normale Java -Eigenschaften erreichen können.
Suchen Sie das oder habe ich die Frage falsch verstanden?