在 Groovy 中从 String 对象动态创建闭包 [英] Create dynamically closures in Groovy from a String object
问题描述
我想使用 Grails (GORM) 中的 Criteria API 创建一个查询.查询必须是这样的:
i would like to create a query with the Criteria API in Grails (GORM). The query will have to be something like this:
MyEntity.createCriteria().list{
assoc{
parent{
eq("code", val)
}
}
}
我需要的是从 String 对象动态构建嵌套闭包.上面示例的字符串将是 "assoc.parent.code"
.我按点分割字符串(通过执行 String.split("\.")
)但我不知道如何构造嵌套闭包:
What i need is to build the nested closure dynamically from a String object. The String for the example above will be "assoc.parent.code"
. I splitted the String by dot (by doing String.split("\.")
) but i don't know how to construct the nested closures:
assoc{
parent{
eq("code", val)
}
}
动态地基于上面拆分的字符串数组.
dynamically based on the array of the splitted Strings above.
推荐答案
createAlias
?.你可以试试这样的:
What about createAlias
?. You could try something like this:
def path = "assoc.parent.code"
def split = path.split(/./)
MyEntity.createCriteria().list {
// this will get you 'createAlias( assoc.parent, alias1 )'
createAlias split.take( split.size() - 1 ), "alias1"
// this will get you 'eq(alias1.code, userInput)'
eq "alias1.${split[-1]}", userInput
}
这个片段不是通用的,但你懂的.
This snippet is not generic, but you get the idea.
更新
不是传统的,但您可以构建一个包含闭包代码的字符串,并使用 GroovyShell
:
Not conventional, but you can build a string containing the code with the closures and evaluate it using GroovyShell
:
assoc = 'assoc.parent.child.name'
split = assoc.split( /./ )
path = split[-2..0] // will get us 'child.parent.assoc';
// we will build it from inside-out
def firstClosure = "{ eq '${split[-1]}', 'john doe' }"
def lastClosure = firstClosure
for (entity in path) {
def criteriaClosure = "{ ${entity} ${lastClosure} }"
lastClosure = criteriaClosure
}
assert lastClosure == "{ assoc { parent { child { eq 'name', 'john doe' } } } }"
def builtClosure = new GroovyShell().evaluate("return " + lastClosure)
assert builtClosure instanceof Closure
这篇关于在 Groovy 中从 String 对象动态创建闭包的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!