Grails / GORM过滤关联结果可以没有N + 1个查询吗?

时间:2012-10-10 14:43:57

标签: grails gorm has-many

我有一个遗留架构,其中hasMany关联的子端有有效的日期记录。在这种情况下,我希望从父对象的结果中排除结束日期记录,并尝试避免使用N + 1查询解决方案。

我可以像这样过滤它们并生成一个合适的查询:

def companyStaffList = CompanyStaff.findAll ( [ max: params.max, sort: params.sort, order: params.order ] ) {
      companyID == params.id && 
      compRecords { effectiveDate < new Date() && endDate > new Date() }
}

生成的查询具有连接和过滤器:

        select [ ...the base fields + the associated fields... ] from company_staff 
    this_ inner join person_compensation comprecord1_ on 
    this_.personID=comprecord1_.personID where 
(this_.companyID=? and ((comprecord1_.effectiveDate<? and comprecord1_.endDate>?))) 
    order by this_.lName asc limit ?

不幸的是,一旦我开始访问相关字段,我看到第二个查询没有传播过滤条件:

select [ the associated fields ] from person_compensation 
comprecord0_ where comprecord0_.personID=?

请告知是否有原则性的方法或者我只是要求太多。

2 个答案:

答案 0 :(得分:1)

您正在访问子集合compRecords,对吗?

然后第一个查询只获取了符合搜索条件的CompRecord个。

想象CompanyStaff staffA有一个CompRecord适合搜索而另一个CompanyStaff.compRecords不适合搜索。该数据不适合完全填写staffA.compRecords。然后,您开始访问CompRecord集合,您还需要枚举那些不适合查询的CompRecord

为了避免N + 1次读取,我会查询子CompanyStaff。但是,您将无法对CompRecord进行分页,而只能对CompRecords.findAll ([max: params.max, sort: params.sort, order: params.order]) { effectiveDate < new Date() && endDate > new Date() && staff { companyID == params.id } } 进行分页:

CompRecord

如果只为CompanyStaff获取一个CompanyStaff,则可以使用HQL获取包含CompRecord和{{1}}字段的无类型集合。

答案 1 :(得分:0)

您可以使用急切提取来避免N + 1。查看GORM文档,其中讨论了“使用渴望获取查询”