Pergunta

Diga que tenho 5 mesas,

tblBlogs     tblBlogPosts     tblBlogPostComment    tblUser    tblBlogMember
BlogId        BlogPostsId       BlogPostCommentId   UserId      BlogMemberId
BlogTitle     BlogId            CommentText         FirstName   UserId
              PostTitle         BlogPostsId                     BlogId
                                 BlogMemberId

Agora, quero recuperar apenas os blogs e postagens para os quais o membro do blog realmente comentou. Então, em suma, como escrevo este velho sql antigo?

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;

Como você pode ver, tudo é interno, então apenas essa linha será recuperada para a qual o usuário comentou em algum post de algum blog. Portanto, suponha que ele ingressou em três blogs cujos IDs são 1,2,3 (os blogs que o usuário ingressou estão no TblblogMembers), mas o usuário apenas comentou no Blog 2 (do Say BlogPostid = 1). Para que a linha seja recuperada e 1,3 não, pois é a junção interna. Como faço para escrever esse tipo de consulta em JPQL?

No JPQL, só podemos escrever consultas simples como digamos:

Select bm.blogId from tblBlogMember Where bm.UserId = objUser;

Onde o Objuser é fornecido usando:

em.find(User.class,1);

Assim, uma vez que obtemos todos os blogs (aqui o BlogId representa um objeto de blog) que o usuário se uniu, podemos passar e fazer todas as coisas sofisticadas. Mas não quero cair nesse negócio de loop e escrever todas essas coisas no meu código Java. Em vez disso, quero deixar isso para o mecanismo de banco de dados. Então, como escrevo o SQL simples acima no JPQL? E que tipo de objeto a consulta JPQL retornará? Porque estou selecionando apenas alguns campos de todas as tabela. Em que classe devo digitar o resultado?

Acho que postei minha exigência corretamente, se não estiver claro, por favor me avise.

ATUALIZAÇÃO: De acordo com a resposta de Pascal, tentei escrever uma consulta JPQL para a consulta SQL acima. Estou enfrentando um pequeno problema. Esta consulta está funcionando, mas está 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

Eu quero modificar isso para:

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

A consulta acima não está funcionando. Como posso resolver esse problema?

Foi útil?

Solução 2

Ok, esta é a resposta final. Demorou uma hora para enquadrar essa linha. Recebi muitos erros estranhos durante essa hora, mas agora meus conceitos são claros o suficiente:

@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")

Outras dicas

No JPQL, só podemos escrever consultas simples (...)

Isso não é verdade e o JPQL suporta [ LEFT [OUTER] | INNER ] JOIN. Para junções internas, consulte a seção 4.4.5.1 Juns internos (o relacionamento se junta) da especificação:

4.4.5.1 Juns internos (o relacionamento se junta)

A sintaxe para a operação de junção interna é

[ INNER ] JOIN join_association_path_expression [AS] identification_variable

Por exemplo, a consulta abaixo se junta ao relacionamento entre clientes e pedidos. Esse tipo de junção normalmente equivale a uma junção sobre um relacionamento de chave estrangeira no banco de dados.

SELECT c FROM Customer c JOIN c.orders o WHERE c.status = 1

A palavra -chave interna pode opcionalmente ser usada:

SELECT c FROM Customer c INNER JOIN c.orders o WHERE c.status = 1

Você só precisa pensar em associação entre entidades.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top