如何在不使用 inList 闭包的情况下使用 GORM 获取 Table A 中不存在于 Table B 中的行?
How to obtain the Table A rows that are not present in Table B with GORM without using an inList closure?
我有一个域定义,它为数据库 table 生成以下示例:
我想执行以下查询:获取与 Table A 相关但不存在于 中的所有域对象TableB
我使用 inList
闭包如下:
List<DMiembro> m = DMiembro.list()
List<DUsuario> usuarios = DUsuario.createCriteria().list(params) {
if (m) {
not {
m*.usuario.id.collate(1000).each { def lista ->
or {
inList("id", lista)
}
}
}
}
eq("enabled", true)
order("nombre", "asc")
} as List<DUsuario>
这很好用。但是,DMiembro
中的数据越来越大。现在我收到与查询大小相关的数据库错误。这是合乎逻辑的,因为查询的参数数量太多
那么,是否有另一种方法来构建查询以收集 DMiembro
中不存在的 Dusuario
个对象?
解决方案一:
您可以在条件中使用 GORM DetachedCriteria
。
import grails.gorm.DetachedCriteria
List<DUsuario> usuarios = DUsuario.createCriteria().list(params) {
not {
'in'('id', new DetachedCriteria(DMiembro).build {
projections {
property 'id'
}
})
}
eq("enabled", true)
order("nombre", "asc")
} as List<DUsuario>
如您所见,这将是一个 NOT IN SQL 请求,这对性能来说不是一个好主意。然而,请求更多 "understandable" 并且仍然是一个很好的解决方案,无论容量如何(请求的执行时间除外)。
方案二:
避免在 DMiembro table 上使用 LEFT JOIN
或 RIGHT JOIN
和 NULL
检查 NOT IN 运算符。请参阅 here 以了解左联接作为普通 SQL 的解决方案。
我有一个域定义,它为数据库 table 生成以下示例:
我想执行以下查询:获取与 Table A 相关但不存在于 中的所有域对象TableB
我使用 inList
闭包如下:
List<DMiembro> m = DMiembro.list()
List<DUsuario> usuarios = DUsuario.createCriteria().list(params) {
if (m) {
not {
m*.usuario.id.collate(1000).each { def lista ->
or {
inList("id", lista)
}
}
}
}
eq("enabled", true)
order("nombre", "asc")
} as List<DUsuario>
这很好用。但是,DMiembro
中的数据越来越大。现在我收到与查询大小相关的数据库错误。这是合乎逻辑的,因为查询的参数数量太多
那么,是否有另一种方法来构建查询以收集 DMiembro
中不存在的 Dusuario
个对象?
解决方案一:
您可以在条件中使用 GORM DetachedCriteria
。
import grails.gorm.DetachedCriteria
List<DUsuario> usuarios = DUsuario.createCriteria().list(params) {
not {
'in'('id', new DetachedCriteria(DMiembro).build {
projections {
property 'id'
}
})
}
eq("enabled", true)
order("nombre", "asc")
} as List<DUsuario>
如您所见,这将是一个 NOT IN SQL 请求,这对性能来说不是一个好主意。然而,请求更多 "understandable" 并且仍然是一个很好的解决方案,无论容量如何(请求的执行时间除外)。
方案二:
避免在 DMiembro table 上使用 LEFT JOIN
或 RIGHT JOIN
和 NULL
检查 NOT IN 运算符。请参阅 here 以了解左联接作为普通 SQL 的解决方案。