【问题标题】:How do I write this JPQL query?如何编写此 JPQL 查询?
【发布时间】:2011-02-20 02:28:25
【问题描述】:

假设我有 5 张桌子,

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

现在我只想检索那些 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;

如您所见,所有内容都是内连接,因此只会检索用户对某个博客的某些帖子发表评论的那一行。所以,假设他/她加入了 3 个 id 为 1,2,3 的博客(用户加入的博客在 tblBlogMembers 中),但用户只在博客 2 中发表了评论(比如 BlogPostId = 1)。所以该行将被检索,而 1,3 不会因为它是内部联接。 JPQL这种查询怎么写?

在 JPQL 中,我们只能编写简单的查询,例如:

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

提供 objUser 的地方是:

em.find(User.class,1);

因此,一旦我们获得了用户加入的所有博客(这里 blogId 代表一个博客对象),我们就可以循环执行所有花哨的事情。但我不想陷入这种循环业务并在我的 Java 代码中编写所有这些东西。相反,我想把它留给数据库引擎去做。那么,如何将上面的纯 SQL 写入 JPQL 呢? JPQL 查询将返回什么类型的对象?因为我只从所有表中选择几个字段。我应该将结果类型转换到哪个类?

我认为我正确地发布了我的要求,如果我不清楚,请告诉我。

更新:根据帕斯卡的回答,我尝试为上述 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

我想将其修改为:

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

上述查询无效。我该如何解决这个问题?

【问题讨论】:

    标签: java orm jpa jpql


    【解决方案1】:

    在 JPQL 中,我们只能编写简单的查询(...)

    这不是真的,JPQL 确实支持 [ LEFT [OUTER] | INNER ] JOIN。对于Inner Joins,请参考规范的4.4.5.1 Inner Joins(关系连接)部分:

    4.4.5.1 内连接(关系连接)

    内连接的语法 操作是

    [ INNER ] JOIN join_association_path_expression [AS] identification_variable
    

    例如,下面的查询连接 之间的关系 客户和订单。这类 join 通常等同于 join over 中的外键关系 数据库。

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

    关键字 INNER 可以是 使用:

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

    您只需要考虑实体之间的关联。

    【讨论】:

    • 我们如何将下面的查询转换为:` SELECT productCode, productName, textDescription FROM products INNER JOIN productlines USING (productline); `
    【解决方案2】:

    好的,这是最终答案。构图这一行花了一个小时。我在这个小时内遇到了许多奇怪的错误,但现在我的概念已经足够清晰了:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-17
      • 2012-05-02
      • 2021-05-27
      • 1970-01-01
      • 2015-08-14
      • 1970-01-01
      • 1970-01-01
      • 2021-01-15
      相关资源
      最近更新 更多