我想基于多个过滤器查询属性并动态构建标准
Domain Class
PatientAttr {
def name
def value
}
标准构建代码
if(filters.size() != 0 ){
def criteria = PatientAttr.createCriteria()
def results = criteria.list{
for (item in filters){
def name = item.name
def filter = item.filter
and{
eq 'name', name
if(filter[0] == "lt")
lt ('value', filter[1] as Double)
else if(filter[0] == "gt")
gt ('value', filter[1] as Double)
else
between ('value', filter[0] as Double, filter[1] as Double)
}
}
}
我发现只评估列表的最后一个“和”语句。条件构建器是否允许您动态构建条件?
上面的代码应该等同于
def results = criteria.list{
and{
eq 'name', "Serum albumin (g/dL)"
gt 'value', 3.5 as Float
}
and{
eq 'name', "M-spike (g/dL)"
gt 'value', 2.3 as Float
}
}
答案 0 :(得分:1)
我不知道你遇到麻烦的原因,但由于查询的默认连词是and
,所以没有理由在你的例子中使用and{}
闭包。您的上述查询与以下内容相同:
def results = criteria.list{
eq 'name', "Serum albumin (g/dL)"
gt 'value', 3.5 as Float
eq 'name', "M-spike (g/dL)"
gt 'value', 2.3 as Float
}
如果你想将顶级项目or
组合在一起,那么你需要将外部块包装在or{}
闭包中:
if(filters.size() != 0 ){
def criteria = PatientAttr.createCriteria()
def results = criteria.list{
or{
for (item in filters){
def name = item.name
def filter = item.filter
and{
eq 'name', name
if(filter[0] == "lt")
lt ('value', filter[1] as Double)
else if(filter[0] == "gt")
gt ('value', filter[1] as Double)
else
between ('value', filter[0] as Double, filter[1] as Double)
}
}
}
}
这将返回一个结果如下的查询:
名称为'血清白蛋白......'且值大于'3.5' OR
名称是'M-spike ...',值大于2.3
OR等
希望这有帮助。
答案 1 :(得分:0)
:
def results = criteria.list{
and{
eq 'name', "Serum albumin (g/dL)"
gt 'value', 3.5 as Float
}
and{
eq 'name', "M-spike (g/dL)"
gt 'value', 2.3 as Float
}
}
你是说要表达:
((name == "Serum albumin (g/dL)") or (value == 3.5))
and
((name == "M-spike (g/dL)") or (value == 3.3))
然后你的代码应该是:
if(filters.size() != 0 ){
def criteria = PatientAttr.createCriteria()
def results = criteria.list{
and{
for (item in filters){
def name = item.name
def filter = item.filter
or {
eq 'name', name
if(filter[0] == "lt")
lt ('value', filter[1] as Double)
else if(filter[0] == "gt")
gt ('value', filter[1] as Double)
else
between ('value', filter[0] as Double, filter[1] as Double)
}
}
}
}
如果你想表达:
((name == "Serum albumin (g/dL)") and (value == 3.5))
and
((name == "M-spike (g/dL)") and (value == 3.3))
然后你的代码应该是:
if(filters.size() != 0 ){
def criteria = PatientAttr.createCriteria()
def results = criteria.list{
and{
for (item in filters){
def name = item.name
def filter = item.filter
eq 'name', name
if(filter[0] == "lt")
lt ('value', filter[1] as Double)
else if(filter[0] == "gt")
gt ('value', filter[1] as Double)
else
between ('value', filter[0] as Double, filter[1] as Double)
}
}
}
因为和是默认操作,你可以省略和方法。