¿Cómo escribo esta consulta JPQL?
Pregunta
Decir que tengo 5 mesas,
tblBlogs tblBlogPosts tblBlogPostComment tblUser tblBlogMember
BlogId BlogPostsId BlogPostCommentId UserId BlogMemberId
BlogTitle BlogId CommentText FirstName UserId
PostTitle BlogPostsId BlogId
BlogMemberId
Ahora quiero recuperar sólo los blogs y mensajes para los que blogMember realidad ha comentado. Así que en resumen, ¿Cómo se escribe este SQL simple y llano?
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 se puede ver, todo es combinación interna, por lo que sólo esa fila se recuperará para el que el usuario ha comentado en un post de algún blog. Así, supongamos que él / ella se ha unido a 3 blogs cuyas ID son 1,2,3 (Los blogs, que son usuario se ha inscrito en tblBlogMembers) pero el usuario sólo ha comentado en el blog 2 (de, por ejemplo BlogPostId = 1). De manera que la fila se recuperará y 1,3 se no como es combinación interna. ¿Cómo escribo este tipo de consulta en JPQL ?
En JPQL, sólo podemos escribir consultas simples, como por ejemplo:
Select bm.blogId from tblBlogMember Where bm.UserId = objUser;
Donde objUser se suministra usando:
em.find(User.class,1);
Por lo tanto una vez que tengamos todos los blogs (aquí blogid representa un objeto de blog), que el usuario se ha unido, que puede recorrer y hacer todas las cosas de lujo. Pero no quiero caer en este negocio bucle y escribir todas estas cosas en mi código Java. En su lugar, quiero dejar que para el motor de base de datos para hacer. Así que, ¿cómo escribo lo anterior SQL normal en JPQL? Y qué tipo de objeto se producirá el retorno consulta JPQL? Porque yo sólo estoy seleccionando unos campos de toda la tabla. En el que la clase debería hacerlo encasillado el resultado a?
Creo Coloqué mi solicitud correctamente, si no me queda claro por favor hágamelo saber.
ACTUALIZACIÓN: Según la respuesta de Pascal, que intentó escribir consulta JPQL para la consulta SQL anterior. Estoy frente a un pequeño problema. Esta consulta es trabajar, pero es 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
Quiero modificar esto:
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 consulta anterior no está funcionando. ¿Cómo puedo solucionar este problema?
Solución 2
Ok, esta es la respuesta final. Se tomó una hora para enmarcar esta línea. Tengo muchos errores extraños durante esta hora, pero ahora mis conceptos son bastante claras:
@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")
Otros consejos
En JPQL, sólo podemos escribir consultas simples (...)
Eso no es verdad y lo hace JPQL apoyo [ LEFT [OUTER] | INNER ] JOIN
. Para combinaciones internas, consulte la sección une 4.4.5.1 interior (Relación une) de la especificación:
une 4.4.5.1 interior (Relación une a)
La sintaxis de la unión interna operación es
[ INNER ] JOIN join_association_path_expression [AS] identification_variable
Por ejemplo, la consulta a continuación se une sobre la relación entre clientes y pedidos. Este tipo de unirse normalmente equivale a una unión más una relación de clave externa en el base de datos.
SELECT c FROM Customer c JOIN c.orders o WHERE c.status = 1
La palabra clave interior puede estar opcionalmente utilizado:
SELECT c FROM Customer c INNER JOIN c.orders o WHERE c.status = 1
Sólo tiene que pensar asociación entre entidades.