Create dynamically closures in Groovy from a String object

后端 未结 2 684
Happy的楠姐
Happy的楠姐 2021-01-07 03:46

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{
   asso         


        
2条回答
  •  耶瑟儿~
    2021-01-07 03:53

    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.


    Update

    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
    

提交回复
热议问题