GORM - 动态查询 - 分离标准?

时间:2014-09-16 17:50:55

标签: sql hibernate grails gorm

我有这样的工作代码:

def criteria = Instance.createCriteria()
def list = criteria.listDistinct {
    eq("saved", true)
    eq("client", client)

    and {
        basicValues {
            eq("fieldA", object.valueA())
            /** CODE BLOCK **/
        }

        customValues {
            eq("fieldB", object.valueB())
            /** CODE BLOCK **/
        }
    }

    or {
        basicValues {
            eq("fieldC", object.valueC())
            /** CODE BLOCK **/
        }

        customValues {
            eq("fieldD", object.valueD())
            /** CODE BLOCK **/
        }
    }
}

如您所见,我正在使用ANDOR部分创建一些标准。在两者中都加入了另一个条件(basicValues / customValues与Instance的关系是1:n)。部分/ **代码块** /是一组条件,它们总是相同的。

到目前为止,我在每个/** CODE BLOCK **/地方放置了相同的条件(例如lt("field", 10)等......)。

我可以将此/** CODE BLOCK **/置于功能中吗?那些条件将在一个地方,代码将更加可读???

2 个答案:

答案 0 :(得分:3)

如果您将/** CODE BLOCK**/设置为单独的关闭,则可以在条件中包含对其的调用。

def commonCriteria = {
    /** CODE BLOCK **/
}

def criteria = Instance.createCriteria()
def list = criteria.listDistinct {
    commonCriteria.delegate = delegate
    eq("saved", true)
    eq("client", client)

    and {
        basicValues {
            eq("fieldA", object.valueA())
            commonCriteria()
        }

        customValues {
            eq("fieldB", object.valueB())
            commonCriteria()
        }
    }
    ...
}

答案 1 :(得分:0)

这是一种可以在纯粹的groovy中保存闭包语句的方法(所有class Deleg部分都是模拟你的场景):

class Deleg {
  def invoked = []

  def execute(fn) {
    fn.delegate = this
    fn()
  }

  def and(closure) { execute(closure) }
  def or(closure) { execute(closure) }

  def methodMissing(String method, args) {
    invoked << [method, args]
  }
}

d = new Deleg()

commonOps = { closure -> 
  return {
    closure()
    lower("a")
    upper("b")
  }
}

fn = {
  and commonOps {
    eq("a")
  }

  or commonOps {
    eq("b")
  }
}

d.execute(fn)

assert d.invoked.size() == 6
assert d.invoked == [
  ["eq",    ["a"]],
  ["lower", ["a"]],
  ["upper", ["b"]],
  ["eq",    ["b"]],
  ["lower", ["a"]],
  ["upper", ["b"]],
]

我不太了解GORM,但我认为你可以做那样的事情,而你只需要commonOps部分。注意它接收并返回一个闭包。

它通过返回一个闭包来执行特定语句,作为闭包参数传​​递,以及通用语句。请注意,您的应用程序不会调用返回的闭包,而是由GORM本身调用。