1

我有几个场景,我想检索单个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. 这似乎是一种非常间接且不直观的方式来表达“请加入该表”。
  2. 没有编译时检查。如果foos关联在 上不存在Advertiser,编译器不会在意。

这是我真的很想看到它工作的方式:

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

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

我有哪些选择?至少,我怎样才能使它更直观地阅读?尽我所能寻找最接近我的理想。

编辑

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

我正在尝试这样做:

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

我也试过

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

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

4

2 回答 2

0

这与您的第一个示例相距不远,但您可能会也可能不会觉得它更直观?

def result = Advertiser.withCriteria {
    eq('id', id)
    fetchMode 'foos', FetchMode.JOIN
    fetchMode 'foos.bars', FetchMode.JOIN
    fetchMode 'bars.baz', FetchMode.JOIN
}
于 2013-05-07T15:10:06.163 回答
0

createCriteria/withCriteria您可以像在子句中使用的那样使用 DSL,where默认情况下会eagerly提取它们。你得到一个列表的结果,所以result[0]应该是它。

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

          }
       }
    }
}

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

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

更新

有关详细信息,请参阅此示例代码

更新2

&&, ||,==不能在条件中使用。他们有专门的 DSL 用于相同的操作,如and{}, or{}, eq(). 看看Grails 标准

Advertiser.withCriteria {
    idEq(id)
    whatsits{}
    foos {
        bars {
            baz
        }
    }
}
于 2013-05-07T15:23:48.213 回答