如何在不使用 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 JOINRIGHT JOINNULL 检查 NOT IN 运算符。请参阅 here 以了解左联接作为普通 SQL 的解决方案。