GRAILS / GORM:动态多重连接

Posted

技术标签:

【中文标题】GRAILS / GORM:动态多重连接【英文标题】:GRAILS / GORM: Dynamic multiple joins 【发布时间】:2018-01-19 20:39:49 【问题描述】:

我有一个复杂的查询,我可以使用 SQL 来解决,但我找不到合适的 GORM 方法来做同样的事情。

我有 Story 对象。每个 Story 对象引用许多 Tag 对象。这是一个单向的 OneToMany 关系:

class Story 
...
    Collection tags
    static hasMany = [
        tags: Tag
    ]
...

几个标签被认为是“别名”(技术上使用单独的“AliasGroup”表,这不是这里的问题)。

现在,我想搜索多个标签。返回的故事必须使用所有这些标签(“匹配所有标签”)进行标记。而且,对于这些标签中的每一个,也应该接受一个“别名”标签。

在 SQL 中,我通过使用动态组合的连接序列来解决这个问题。例如,如果给定两个标签,都具有多个“别名”,则生成的 SQL 语句如下所示(使用实际的 SQL 行名):

select s.id from story 
   join story_tag st1 on s.id = st1.story_id 
   join story_tag st2 on s.id = st2.story_id 
where 
   st1.tag_id in (<list of ids for tag1 and all its aliases>) and
   st2.tag_id in (<list of ids for tag2 and all its aliases>)

重要的是要理解这不能写成一个单一的连接,因为这样 SAME 标记必须在两组标记列表中,这不是我想要的。

因此,此语句运行良好。但我想直接使用 grails 来实现同样的目标。关于连接的 GORM 文档相当简洁,但我认为使用关联查询和“和”它们一起的功能会给出正确的结果。所以我尝试了:

def c = Story.createCriteria()
def stories = c.list 
    and 
        srchTags.each  tag ->
            def ids = []

            tag.aliasGroup.aliases.each  alias ->
                ids << alias.id
            

            tags 
                inList('id', ids)
            
        
    

如果我只使用一个标签作为输入,这很好用。 IE。别名标签ID列表已正确解析,该语句原则上有效。

但如果我使用两个或更多标签,它就不能正常工作。代码运行,但 GORM 似乎只是创建了错误的 SQL 查询,似乎它再次尝试将每个标签与所有无法工作的匹配列表匹配。

我意识到这个问题并不容易理解,更难以正确描述。

有没有人知道如何为这个问题创建一个合适的 Grails 查询?

【问题讨论】:

没有什么能阻止你使用mrhaki.blogspot.co.uk/2014/03/…。如果你环顾四周,你应该会发现这方面的负担。您还可以查看 HQL 查询,但您的 hasMany 对象似乎是一个内部 Collection ? 【参考方案1】:

现在在一个工作项目中,我有几个无法转换为 gorm(criteria, where) 的 sql 查询。由于需要继续前进,我在 grails 中使用了本机 sql 查询,一切顺利。

具体实现方法请看文章Using Hibernate Native SQL Queries。

我知道你不能总是决定使用哪种方法,但手头有这个工具总是有用的。

希望对你有用。问候

【讨论】:

感谢您的建议,这正是我正在使用的解决方法。但它有一些缺点,我真的不喜欢它。我希望有更好的方法...

以上是关于GRAILS / GORM:动态多重连接的主要内容,如果未能解决你的问题,请参考以下文章

Grails + GORM:GORM 中默认的 equals() 实现是啥?

Grails/GORM“入”标准

linuxtarlib依赖库多重连接

Grails / GORM,禁用一级缓存

如何在 Grails/GORM 中将派生属性设置为小写?

在 Grails/GORM 中定义默认排序顺序