是否有更清晰,更Grailsy的方式来编写此查询?

时间:2013-05-07 14:55:42

标签: grails gorm eager-loading hibernate-criteria detachedcriteria

我有几个场景,我想要检索单个Advertiser并渴望获取其大部分对象图。我绝对不想默认这样做,所以我一直在寻找正确的方法来执行单个查询。这是我到目前为止所提出的:

    Advertiser.createCriteria().get {
        eq('id', id)
        createAlias('foos', 'foos', CriteriaSpecification.LEFT_JOIN)
        createAlias('foos.bars', 'bars', CriteriaSpecification.LEFT_JOIN)
        createAlias('bars.baz', 'bazzes', CriteriaSpecification.INNER_JOIN)
    }

这有效,但我不喜欢它有几个原因。

  1. 这似乎是一种非常间接且不直观的说法,“请加入dang table吧。”
  2. 没有编译时检查。如果foos上不存在Advertiser关联,则编译器不关心。
  3. 以下是我真正喜欢看到它的工作方式:

    Advertiser.where {
        id == id
        foos {
            bars {
                baz
            }
        }
    }
    

    但是这没有任何加入;显然,如果您实际上没有为该属性指定条件(><==等),它将忽略您。

    我有什么选择?我怎样才能使这个更直观易读?寻找最接近我的理想,因为我可以得到。

    修改

    我已经尝试了下面的一些建议但事情没有用,可能部分是因为我的语法不正确。假设我需要急切地获取另一个名为whatsits

    的第一级关联

    我试图这样做:

    Advertiser.withCriteria {
        idEq(id)
        whatsits
        foos {
            bars {
                baz 
            }
        }
    }
    

    我也试过

    Advertiser.withCriteria {
        idEq(id) && whatsits && foos {
            bars {
                baz
            }
        }
    }
    

    但是不同的方法会产生不同的异常,奇怪的查询等等。

2 个答案:

答案 0 :(得分:0)

这与你的第一个例子相距不太远,但是你可能会或者可能不会觉得它更直观?

def result = Advertiser.withCriteria {
    eq('id', id)
    fetchMode 'foos', FetchMode.JOIN
    fetchMode 'foos.bars', FetchMode.JOIN
    fetchMode 'bars.baz', FetchMode.JOIN
}

答案 1 :(得分:0)

您可以在createCriteria/withCriteria子句中使用where中的DSL,默认情况下eagerly获取它们。您将结果作为列表获取,因此result[0]应该是它。

def result = Advertiser.withCriteria {
    idEq(id)
    foos{
       bars{
          baz{

          }
       }
    }
}

获得结果后,您可以检查是否存在关联,即

if(result[0].foos){...}

<强>更新

有关详细信息,请参阅此Sample Code

<强> UPDATE2

&&||==不能用于标准。他们为and{}or{}eq()等相同的操作设置了专用的DSL。看看Grails Criteria

Advertiser.withCriteria {
    idEq(id)
    whatsits{}
    foos {
        bars {
            baz
        }
    }
}