withCriteria获取关联对象的列表

时间:2015-10-31 18:20:00

标签: grails criteria

我是Grails的新手,发现很难理解db标准。

任何人都可以提供以下帮助:

这是我的域名结构:

- 评论    --CommentGroups       - 评论

所以我的域类看起来像(简体):

class Comment {
    String commentTitle
    String comment
    CommentGroup commentGroup   
    static hasMany = [commentGroups:CommentGroup]
    static constraints = {
        commentGroup nullable:true
    }
}

class CommentGroup{
    String groupTitle
    static constraints = {
        groupTitle blank:true, nullable:true
    }
}

所以我的评论可以有很多评论组,而这些评论组可以有很多评论,但我的评论组上没有hasMany评论。相反,我通过将commentGroup分配给评论来将评论与组相关联。

这正确地保存到MySQL DB,我已设法使用以下代码回退评论组:

    def testimonialList = Comment.withCriteria {
        eq 'approved', true
        isNull 'commentGroup'
        order('dateCreated', 'desc')
        order('displayPriority','desc')
        maxResults max
        firstResult offset
    }

我现在需要实现的是通过将当前的Comment CommentGroup与相关的Comment CommentGroup匹配并将它们保存在每个CommentGroup下的列表中来拉回当前Comment CommentGroups的所有注释。

所以我最终得到了一个类似于:

的对象结构
Comment
   CommentGroup1
      Comment1
      Comment2
      Comment3
   CommentGroup2
      Comment1
      Comment2
      Comment3

任何人都可以帮我完成我的标准查询以实现这一目标。

提前谢谢。

1 个答案:

答案 0 :(得分:2)

要获得您正在寻找的结果,您需要采用不同的方法。

问题

您将域模型描述为:注释 - 1 ----- n - CommentGroup- 1 - --- 名词 - 注释

如果是这种情况,您将能够轻松实现目标。但事实上你所拥有的是:评论 - 1 ----- n - CommentGroup- n ---- - 1 - 注释

由于CommentGroup没有对Comment的引用,因此从CommentGroup转到Comment很有挑战性。

努力寻求解决方案

对于给定的CommentGroup,你可以得到Comment这样的内容:

def comments = Comment.withCriteria {
    eq('commentGroup', commentGroup)
}

如果你有一个CommentGroup的列表,那么你可以得到他们所有的Comment

def comments = Comment.withCriteria {
    inList('commentGroup', commentGroups)
}

所以你必须:

  1. 运行查询以获取您感兴趣的Comment列表。
  2. 使用.commentGroups的{​​{1}}属性获取Comments的列表。
  3. 运行第二个查询以获取CommentGroup s的Comment
  4. 将所有东西拼凑成您需要的结构;可能使用嵌套的CommentGroup s。
  5. 前三个步骤看起来像这样:

    Map

    更好的方法

    创建您描述的域模型会更加简单,其中包含适用于此目的的关联:

    def comments = Comment.withCriteria {
        eq 'approved', true
        isNull 'commentGroup'
        ...
    }
    
    def commentGroups = comments*.commentGroups
    
    def comments = Comment.withCriteria {
        inList('commentGroup', commentGroups)
    }
    

    使用此模型,一旦您拥有class Comment { String commentTitle String comment static belongsTo = CommentGroup static hasMany = [commentGroups:CommentGroup] static constraints = { commentGroup nullable:true } } class CommentGroup{ String groupTitle static hasMany = [comments: Comment] static constraints = { groupTitle blank:true, nullable:true } } ,就可以获得Comment CommentGroup

    Comment

    但是为了更接近您正在寻找的输出,您最好使用HQL。那是因为条件查询不能项目根实体。例如,如果您像这样查询def otherComments = comment.commentGroups*.comments Comment,您可以返回Comment.withCriteria {...} s(根实体,这是默认行为),或者您可以 Comment的项目属性。它是/或。但是HQL没有这个限制。

    Comment

    结果看起来像这样:

    def hql = """
    SELECT   c, cgs, cs
    FROM     Comment as c
             INNER JOIN c.commentGroups as cgs
             INNER JOIN cgs.comments as cs
    WHERE    c.approved = true
             // Ignoring, c.commentGroup IS NULL, because it doesn't make sense.
    ORDER BY c.dateCreated DESC, c.displayPriority DESC
    """
    
    def result = Comment.executeQuery(hql, null, [maxResults: max])
    

    基本上它是你要求的结构,但是作为查询结果集扁平化。

    我有一个关于如何查询GORM关联的article,其中我演示了影响关联对您可以创建的查询的影响。我认为你会发现它有助于学习标准查询。