Wee*_*zle 6 grails groovy createcriteria
我正在努力建立一个createCriteria
动态的.到现在为止还挺好:
obj
是我想要的域对象
rulesList
是一个地图列表,其中包含要搜索的字段,要使用的运算符以及要搜索的值
def c = obj.createCriteria()
l = c.list (max: irows, offset: offset) {
switch(obj){ //constrain results to those relevant to the user
case Vehicle:
eq("garage", usersGarage)
break
case Garage:
users {
idEq(user.id)
}
break
}
rulesList.each { rule ->
switch(rule['op']){
case 'eq':
eq("${rule['field']}", rule['value'])
break
case 'ne':
ne("${rule['field']}", rule['value'])
break
case 'gt':
gt("${rule['field']}", rule['value'])
break;
case 'ge':
ge("${rule['field']}", rule['value'])
break
case 'lt':
lt("${rule['field']}", rule['value'])
break
case 'le':
le("${rule['field']}", rule['value'])
break
case 'bw':
ilike("${rule['field']}", "${rule['value']}%")
break
case 'bn':
not{ilike("${rule['field']}", "${rule['value']}%")}
break
case 'ew':
ilike("${rule['field']}", "%${rule['value']}")
break
case 'en':
not{ilike("${rule['field']}", "%${rule['value']}")}
break
case 'cn':
ilike("${rule['field']}", "%${rule['value']}%")
break
case 'nc':
not{ilike("${rule['field']}", "%${rule['value']}%")}
break
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
上面的代码工作正常,只是看起来有点冗长的switch语句.但是,如果我想添加选择匹配任何规则或所有规则的功能,该怎么办?我需要有条件地将规则放在一个or{}
.我做不了类似的事情
if(groupOp == 'or'){
or{
}
Run Code Online (Sandbox Code Playgroud)
在我通过rulesList然后
if(groupOp == 'or'){
}
}
Run Code Online (Sandbox Code Playgroud)
之后.我能想到的就是为每个条件重复代码:
if(groupOp == 'or'){
or{
rulesList.each { rule ->
switch(rule['op']){
...
}
}
}
}
else{
rulesList.each { rule ->
switch(rule['op']){
...
}
}
Run Code Online (Sandbox Code Playgroud)
现在代码看起来很草率和重复.假设我想搜索域对象属性的属性?(例如:我想要归还轮胎属于特定品牌的车辆; vehicle.tires.brand,或者司机与名称匹配的车辆; vehicle.driver.name).我是否必须做以下事情:
switch(rule['op']){
case 'eq':
switch(thePropertiesProperty){
case Garage:
garage{
eq("${rule['field']}", rule['value'])
}
break
case Driver:
driver{
eq("${rule['field']}", rule['value'])
}
break
}
break
case 'ne':
...
}
Run Code Online (Sandbox Code Playgroud)
首先,您可以使用GString作为方法名称来简化您的大开关:
case ~/^(?:eq|ne|gt|ge|lt|le)$/:
"${rule['op']}"("${rule['field']}", rule['value'])
break
Run Code Online (Sandbox Code Playgroud)
同样的技巧适用于和/或:
"${(groupOp == 'or') ? 'or' : 'and'}"() {
rulesList.each { rule ->
switch(rule['op']){
...
}
}
}
Run Code Online (Sandbox Code Playgroud)
或者您可以先将闭包赋值给变量,然后调用or(theClosure)
或and(theClosure)
适当调用.最后,对于"属性"搜索,如果添加
createAlias('driver', 'drv')
createAlias('garage', 'grg')
Run Code Online (Sandbox Code Playgroud)
在条件闭包的顶部,您可以查询诸如eq('drv.name', 'Fred')
无需添加干预driver {...}
或garage {...}
节点之类的事情.
归档时间: |
|
查看次数: |
4412 次 |
最近记录: |