过滤多个关联和可选的where子句

时间:2012-03-23 11:49:31

标签: grails gorm

我有几个域类,它们之间有一些简单的关联,如下所示:

class Business {
  String name
  City city
  Industry industry
}

class City {
  String name
}

class Industry {
  String name
}

在我的申请中,我希望有一个“过滤器”,可以根据城市和行业过滤所有商家的列表。我能够将过滤器中的城市和行业id从商业控制器中获取,但是,当我到控制器进行过滤时,我有这样的代码:

...
def industry = Industry.get(params.int('industryid'))
def city = City.get(params.int('cityid'))

def businessList = Business.findAllByIndustryAndCity(industry, city)
...

当City和Industry字段都有值时,此代码有效。但是,有时用户可能只想按城市或行业进行过滤,而不是两者都过滤。在这种情况下,过滤器失败,因为当任一值为null时,不返回任何结果。我怎么能指定如果其中一个关联值是“null”,那么“find”查询应该完全删除这个约束?即匹配该字段的“全部”

请注意,我意识到将if语句检查值是否为null然后基于此执行不同的“find”语句会很容易。但是,虽然这可以使用两个值,但我认为它不会随着更多可过滤值的增加而扩展。

1 个答案:

答案 0 :(得分:3)

您可以建立标准。

def c = Business.createCriteria()
def results = c.list{
    and {
        if (industry) {
            eq("industry", industry)
        }
        if (city) {
            eq("city", city)
        }
    }
}

检查grails docs中的参考here

但是,您的代码需要对N个参数进行N + 1次查询。也许您可以使用标准理念将其减少为一个查询?如果您的Business实体拥有IndustryCity的外键,则应该有效:

def c = Business.createCriteria()
def results = c.list{
    and {
        if (params.industryid) {
            eq("industry_id", params.industryId as Long)
        }
        if (params.cityid) {
            eq("city_id", params.cityid as Long)
        }
    }
}

这两个例子都未经过测试,但您应该明白这一点。