我有一个遗留模式,其中在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=?
请告知是否有原则的方法可以做到这一点,或者我只是要求太多。
您正在访问子集合compRecords
,对吗?
然后,第一个查询仅获取符合搜索条件的CompRecord
。
想象一下,CompanyStaff staffA
有一个适合搜索的CompRecord
,另一个不适合搜索。该数据不适合完全填写CompanyStaff.compRecords
。然后开始访问staffA.compRecords
集合,您还需要枚举不适合查询的CompRecord
。
为了避免 N+1 次读取,我会查询子CompRecord
。但是这样你就不能对CompanyStaff
s进行分页,而只能对CompRecord
s进行分页:
CompRecords.findAll ([max: params.max, sort: params.sort, order: params.order]) {
effectiveDate < new Date() && endDate > new Date() &&
staff {
companyID == params.id
}
}
如果可以只获取CompanyStaff
的单个CompRecord
,则可以使用 HQL 获取包含CompanyStaff
和CompRecord
字段的非类型化集合。
您可以使用预先获取来避免 N+1。查看 GORM 文档,其中讨论了"使用预先获取进行查询"