如何编写涉及三个域的相对简单的标准查询?

时间:2015-09-04 21:44:12

标签: grails gorm criteria

仅为后台,让我们有三个域类:

class Group {
    Long id
    Person person
}

class Person {
    Long id
    Country country
    String name
}

class Country {
    Long id
}

因此,考虑到这些类,我将获得一个Group对象的id以及一个Country对象的id。我想基于这两个获取Person对象列表。

看起来相对简单,但我对标准查询不熟悉,所以我很难弄清楚我做错了什么。这就是我到目前为止所做的:

def c = Group.createCriteria()
def names = c.list (order: "asc") {
    createAlias('person', 'p')
    createAlias('p.country', 'c')
    and {
        eq ('c.id', Long.valueOf(countryId))
        eq ('id', groupId)
    }
    projections {
        property('p.name')
    }
}

当然,这是错误的,因为它会抛出错误。有人可以让我知道我做错了什么吗?

感谢您的帮助!

2 个答案:

答案 0 :(得分:0)

static def searchPersons(Map params) {
    return Group.createCriteria().list(params, {
        if(params.groupId) {
            eq('id', params.groupId.toLong())
        }
        person {
            order('name')
            if(params.countryId) {
                country {
                    eq('id', params.countryId.toLong())
                }
            }
        }
        projections {
            property('person')
        }

    })
}

但是,在您的域名上添加必要的关联( hasMany 等)可能会更好。

答案 1 :(得分:0)

您可以做的第一件事是改善域类之间的关联。这将有助于简化条件查询(并在以后阻止猴子修补)。

在您的示例中,PersonGroup之间的关联是一对多;一个人可以有很多团体。这可能是你的意图,但也意味着一个团体只能有一个人。基本上,没有办法将人们聚集在一起。

我将假设你想要多对一的关系,以便许多Person(人)可以在同一个Group。考虑到这一点,域类(保留显式ID)将如下所示:

class Group {
    Long id
}

class Person {
    Long id
    Country country
    String name
    Group group
}

class Country {
    Long id
}

对于查询,由于您的预期结果是Person的实例,因此最好从Person开始,而不是Group

人员实例列表

以下是获取Person个实例列表的方法。

查询

def people = Person.where {
    country.id == countryId
    group.id == groupId
}.list()

标准查询

def people = Person.withCriteria {
    country {
        eq 'id', countryId as Long
    }

    group {
        eq 'id', groupId
    }
}

人名列表

请注意,您的问题和示例之间存在差异。您要求提供Person个实例的列表,但您的示例演示了如何获取Person 名称的列表。

以下是如何获取Person个实例的名称列表。

查询

def names = Person.where {
    country.id == countryId
    group.id == groupId
}.projections {
    property 'name'
}.list()

标准查询

def names = Person.withCriteria {
    country {
        eq 'id', countryId as Long
    }

    group {
        eq 'id', groupId
    }

    projections {
        property 'name'
    }
}