Come faccio a scrivere questa query JPQL?
Domanda
Dire che ho 5 tavoli,
tblBlogs tblBlogPosts tblBlogPostComment tblUser tblBlogMember
BlogId BlogPostsId BlogPostCommentId UserId BlogMemberId
BlogTitle BlogId CommentText FirstName UserId
PostTitle BlogPostsId BlogId
BlogMemberId
Ora voglio recuperare solo quei blog e post per i quali blogMember ha effettivamente commentato. Così, in breve, Come faccio a scrivere questa pianura vecchia 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;
Come si può vedere, tutto è unire interno, in modo che solo quella riga verrà recuperato per i quali l'utente ha commentato alcuni post di qualche blog. Così, supponiamo che lui / lei si è unita 3 i blog i cui ID sono 1,2,3 (I blog che l'utente ha aderito sono in tblBlogMembers) ma l'utente ha commentato solo in blog 2 (di dire BlogPostId = 1). Così quella riga verrà recuperato e 1,3 si non come è Join interno. Come faccio a scrivere questo tipo di query in JPQL ?
In JPQL, si può solo scrivere query semplici come dire:
Select bm.blogId from tblBlogMember Where bm.UserId = objUser;
Dove objUser viene fornito con:
em.find(User.class,1);
In questo modo una volta che otteniamo tutti i blog (qui blogId rappresenta un oggetto blog) che l'utente ha aderito, siamo in grado di scorrere e fare tutte le cose di fantasia. Ma io non voglio cadere in questo business looping e scrivere tutte queste cose nel mio codice Java. Invece, voglio lasciare che per il motore di database di fare. Allora, come faccio a scrivere quanto sopra SQL pianura in JPQL? E che tipo di oggetto sarà il ritorno di query JPQL? Perché io sto selezionando solo alcuni campi di tutto tavolo. In quale classe dovrei typecast il risultato?
Credo che ho postato la mia richiesta in modo corretto, se non mi è chiaro per favore fatemelo sapere.
UPDATE: Come per ogni risposta di Pascal, ho provato a scrivere interrogazione JPQL per la query SQL sopra. Sono di fronte a un piccolo problema. Questa query è lavoro, ma è incompleta:
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
Voglio modificare questo a:
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
La query sopra non funziona. Come posso risolvere questo problema?
Soluzione 2
Ok, questa è la risposta definitiva. Ci sono voluti un'ora per inquadrare questa linea. Ho avuto molti strani errori durante questa ora, ma ora i miei concetti sono abbastanza chiare:
@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")
Altri suggerimenti
In JPQL, si può solo scrivere query semplici (...)
Non è vero e JPQL supportati da [ LEFT [OUTER] | INNER ] JOIN
. Per join interni, fare riferimento alla sezione 4.4.5.1 interno entra a far parte (Relationship unisce) della specifica:
entra a far parte 4.4.5.1 interno (entra a far parte di relazione)
La sintassi per aderire al interno operazione è
[ INNER ] JOIN join_association_path_expression [AS] identification_variable
Ad esempio, la query di seguito si unisce il rapporto tra clienti e ordini. Questo tipo di unire in genere equivale a un join sopra una relazione di chiave esterna nella Banca dati.
SELECT c FROM Customer c JOIN c.orders o WHERE c.status = 1
La parola chiave interno può essere opzionalmente utilizzato:
SELECT c FROM Customer c INNER JOIN c.orders o WHERE c.status = 1
Hai solo bisogno di pensare associazione tra entità.