说我有5张桌子,
tblBlogs tblBlogPosts tblBlogPostComment tblUser tblBlogMember
BlogId BlogPostsId BlogPostCommentId UserId BlogMemberId
BlogTitle BlogId CommentText FirstName UserId
PostTitle BlogPostsId BlogId
BlogMemberId
Run Code Online (Sandbox Code Playgroud)
现在我想只检索blogMember实际评论过的那些博客和帖子.简而言之,我该如何编写这个普通的旧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;
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,一切都是内连接,因此只检索用户在某些博客的某些帖子上评论过的那一行.所以,假设他/她加入了3个博客,其ID为1,2,3(用户加入的博客在tblBlogMembers中),但用户只在博客2中评论过(比如BlogPostId = 1).因此,将检索该行,并且1,3将不会因为它是内部联接.如何在JPQL中编写这种查询?
在JPQL中,我们只能编写简单的查询,例如:
Select bm.blogId from tblBlogMember Where bm.UserId = objUser;
Run Code Online (Sandbox Code Playgroud)
使用objUser提供的地方:
em.find(User.class,1);
Run Code Online (Sandbox Code Playgroud)
因此,一旦我们获得了用户加入的所有博客(此处为blogId代表博客对象),我们就可以循环并完成所有奇特的事情.但我不想陷入这种循环业务,并在我的Java代码中编写所有这些内容.相反,我想把它留给数据库引擎来做.那么,我如何将上述纯SQL写入JPQL?JPQL查询返回什么类型的对象?因为我只从所有表中选择几个字段.我应该在哪个类中对结果进行类型转换?
我想我正确地发布了我的要求,如果我不清楚请告诉我.
更新:根据pascal的回答,我尝试为上述SQL查询编写JPQL查询.我面临一个小问题.此查询正在运行,但不完整:
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
Run Code Online (Sandbox Code Playgroud)
我想将其修改为:
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
Run Code Online (Sandbox Code Playgroud)
以上查询无效.我怎么解决这个问题?
Pas*_*ent 14
在JPQL中,我们只能编写简单的查询(...)
这不是真的,JPQL确实支持[ LEFT [OUTER] | INNER ] JOIN
.对于内连接,请参阅规范的4.4.5.1内连接(关系连接)一节:
4.4.5.1内部连接(关系连接)
内部联接操作的语法是
Run Code Online (Sandbox Code Playgroud)[ INNER ] JOIN join_association_path_expression [AS] identification_variable
例如,下面的查询将加入客户与订单之间的关系.这种类型的连接通常等同于数据库中外键关系的连接.
Run Code Online (Sandbox Code Playgroud)SELECT c FROM Customer c JOIN c.orders o WHERE c.status = 1
可以选择使用关键字INNER:
Run Code Online (Sandbox Code Playgroud)SELECT c FROM Customer c INNER JOIN c.orders o WHERE c.status = 1
您只需要考虑实体之间的关联.
好的,这是最终的答案.花了一个小时来构建这一行.在这一小时里我遇到了许多奇怪的错误,但现在我的概念已经足够清楚了:
@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")
Run Code Online (Sandbox Code Playgroud)