Wie schreibe ich diese JPQL Abfrage?
Frage
sagen, ich habe 5 Tabellen,
tblBlogs tblBlogPosts tblBlogPostComment tblUser tblBlogMember
BlogId BlogPostsId BlogPostCommentId UserId BlogMemberId
BlogTitle BlogId CommentText FirstName UserId
PostTitle BlogPostsId BlogId
BlogMemberId
Jetzt möchte ich nur die Blogs und Beiträge abzurufen, für die blogMember tatsächlich kommentiert. Also kurz gesagt, wie schreibe ich diese einfache alte SQL?
SELECT b.BlogTitle, bp.PostTitle, bpc.CommentText FROM tblBlogs b
INNER JOIN tblBlogPosts bp on b.BlogId = bp.BlogId
INNER JOIN tblBlogPostComment bpc on bp.BlogPostsId = bpc.BlogPostsId
INNER JOIN tblBlogMember bm ON bpc.BlogMemberId = bm.BlogMemberId
WHERE bm.UserId = 1;
Wie Sie sehen können, ist alles Inner verbinden, so dass nur diese Zeile abgerufen werden, für die der Benutzer auf einige Posten von einigen Blog kommentiert hat. So sei angenommen, er / sie hat drei Blogs verbunden, deren ids sind 1,2,3 (Die Blogs, die Benutzer beigetreten sind in tblBlogMembers), aber der Benutzer hat nur in Blog 2 (von etwa BlogPostId = 1) kommentiert. So dass Zeile abgerufen wird und 1,3 wird nicht, wie es ist Inner Join. Wie schreibe ich diese Art der Abfrage in JPQL ?
In JPQL, können wir nur schreiben einfache Abfragen wie gesagt:
Select bm.blogId from tblBlogMember Where bm.UserId = objUser;
Wo objUser geliefert mit:
em.find(User.class,1);
So, wenn wir alle Blogs erhalten (hier stellt blogid ein Blog-Objekt), welcher Benutzer beigetreten ist, können wir durchlaufen und alle Phantasie Dinge zu tun. Aber ich will nicht in dieser Schleife Geschäft fallen und all diese Dinge in meinem Java-Code schreiben. Stattdessen möchte ich, dass verlassen für die Datenbank-Engine zu tun. Also, wie schreibe ich die obige Ebene SQL in JPQL? Und welche Art von Objekt wird die JPQL Abfrage Rückkehr? Da ich nur die Auswahl einige Felder aus allen Tabelle. In welcher Klasse sollte ich Typumwandlung das Ergebnis?
Ich glaube, ich meine Anforderung korrekt geschrieben, wenn ich klar bin nicht lassen Sie es mich wissen.
UPDATE: Wie pro pascal Antwort, habe ich versucht, JPQL Abfrage für die obige SQL-Abfrage zu schreiben. Ich bin ein kleines Problem. Diese Abfrage funktioniert, aber unvollständig ist:
SELECT bm.blogId FROM BlogMembers bm
INNER JOIN bm.blogId b
INNER JOIN b.blogPostsList bp
INNER JOIN bp.blogPostCommentList bpc
WHERE bm.userId = :userId
Ich möchte dies ändern:
SELECT bm.blogId FROM BlogMembers bm
INNER JOIN bm.blogId b
INNER JOIN b.blogPostsList bp
INNER JOIN bp.blogPostCommentList bpc
WHERE bpc.blogMembersId = bm.blogMembersId AND bm.userId = :userId
Die obige Abfrage funktioniert nicht. Wie kann ich dieses Problem lösen?
Lösung 2
Ok, das ist die endgültige Antwort. Es dauerte 1 Stunde diese eine Zeile umrahmen. Ich habe viele seltsame Fehler in dieser Stunde, aber jetzt meine Begriffe sind klar:
@NamedQuery(name = "BlogMembers.findBlogsOnWhichCommentsAreMade",
query = "SELECT bm.blogId FROM BlogMembers bm INNER JOIN bm.blogId b
INNER JOIN b.blogPostsList bp INNER JOIN bp.blogPostCommentList bpc
INNER JOIN bpc.blogMembersId bmt WHERE bm.userId = :userId")
Andere Tipps
In JPQL, können wir nur einfache Abfragen schreiben (...)
Das ist nicht wahr und JPQL tut Unterstützung [ LEFT [OUTER] | INNER ] JOIN
. Für Innere Verknüpfungen, finden Sie im Abschnitt 4.4.5.1 Innere Verknüpfungen (Beziehung tritt) die Spezifikation:
4.4.5.1 Innere Verknüpfungen (Beziehung tritt)
Die Syntax für die innere Verknüpfung Betrieb ist
[ INNER ] JOIN join_association_path_expression [AS] identification_variable
Zum Beispiel unter der Abfrage verknüpft über die Beziehung zwischen Kunden und Aufträge. Diese Art von Join entspricht typischerweise zu einem Join über eine Fremdschlüsselbeziehung in der Datenbank.
SELECT c FROM Customer c JOIN c.orders o WHERE c.status = 1
Das Schlüsselwort INNER kann optional sein verwendet:
SELECT c FROM Customer c INNER JOIN c.orders o WHERE c.status = 1
Sie müssen nur Assoziation zwischen Entitäten denken.