我是Grails的新用户,我很难通过GORM设置进行更复杂的查询。
我有两个域对象/表,LOCATION和REASON,它们有多对多的映射,由LOCATION_REASON表管理:
Location.groovy:
class Location {
String description
// other fields
static hasMany = [reasons: Reason]
static mapping = {
sort description:"asc"
id generator:'native', params:[sequence:'ATTENDANCE_TRACKER.ID_SEQ']
reasons joinTable: [name: 'LOCATION_REASON', key: 'LOCATION_ID', column: 'REASON_ID'], cascade: 'none'
}
static namedQueries = {
findAllWhereReasonIsNot { reasonId ->
reasons { ne('id', reasonId) }
}
}
//Other stuff
}
Reason.groovy:
class Reason {
String description
//other fields
static hasMany = [locations: Location]
static mapping = {
id generator:'native', params:[sequence:'ATTENDANCE_TRACKER.ID_SEQ']
locations joinTable: [name: 'LOCATION_REASON', key: 'REASON_ID', column: 'LOCATION_ID'], cascade: 'none'
}
//Other stuff
}
命名查询'findAllWhereReasonIsNot',功能不如我所愿。我想要一个查询来完成获取尚未与指定原因相关联的所有位置。
在SQL术语中,我想要这个:
select * from location where id not in(select location_id from location_reason where reason_id = :reasonId);
但是,当生成hibernate SQL时,当前实现的内容看起来或多或少(编辑为仅包含相关信息,并且具有合理的'select as'名称):
select * from
(
select
this_.id as loc_location_id,
this_.description as location_description,
reasons3_.LOCATION_ID as loc_reas_location_id,
reasons3_.REASON_ID as loc_reas_reason_id,
reasons_al1_.id as reas_reason_id,
reasons_al1_.description as reason_description
from location this_
inner join location_reason reasons3_ on this_.id=reasons3_.LOCATION_ID
inner join reason reasons_al1_ on reasons3_.REASON_ID=reasons_al1_.id
where (reasons_al1_.id <> :reasonId)
order by lower(this_.description) asc
);
这会生成每个位置的多个副本的列表,每个位置对应一个副本。这可以防止生成的列表实际排除与原始reasonId关联的位置,因为其他原因与该位置相关联。
我对Criteria和HQL进行了一些研究,但是无法获得生成的查询...似乎Criteria和HQL有一些限制,所以我甚至不确定它是否可行。有谁知道如何在命名查询中完成那个简单的'not in'子查询?
答案 0 :(得分:0)
因为有许多关系,你需要创建一个别名:
示例:
Location.createCriteria().list(){
createAlias("reasons","r")
not{'in'("r.id", arrayList)}
}
这也适用于命名查询。
答案 1 :(得分:0)
因此,经过多次试验和错误,我得到了一个有效的HQL查询:
Location.findAll("from Location loc where loc not in (select l from Location l join l.reasons as r where r.id = ?) order by loc.description")
非常感谢cfrick让我指出了正确的方向。之前我曾简要介绍过HQL,但误解了一些Grails文档,认为它只支持HQL的'where'子句。我还试图直接访问联接表
这是我学到的东西: