1

I have requirement in which i need some logic of criteria query to be config driven. Earlier i used to query like : e.g.:

User.createCriteria().list{
     or{ 
        eq('username',user.username)
        eq('name',user.name)
     }
}

But, i need this to be configurable in my use case so, i try this code snippet.

def criteriaCondition= grailsApplication.config.criteriaCondition?:{user->
         or{
           eq('username',user.username)
           eq('name',user.name)   
         }
}

User.createCriteria().list{criteriaCondition(user)}

But, This doesn't work for me. I am getting missing method exception for "or" I tried few solution from some sources but it didn't worked for me.

So, can anyone help me :

1) How to make the above given code work. 2) Any other better way for my use case.

Thanks in advance!!!

4

2 回答 2

2

您必须将 criteriaBuilder 对象传递给闭包,如下所示:

def criteriaCondition = grailsApplication.config.criteriaCondition ?: { cb, user ->
     cb.or{
       cb.eq('username',user.username)
       cb.eq('name',user.name)   
     }
}

def criteriaBuilder = User.createCriteria()

criteriaBuilder.list{
    criteriaCondition(criteriaBuilder, user)
}

显然,Config.groovy 中的闭包也必须具有相同的参数列表,包括cb

于 2013-09-19T10:21:26.540 回答
2

标准构建器机制的工作方式,该list方法期望传递一个它将调用的闭包,而您当前的代码正在调用criteriaCondition闭包本身,而不是让标准构建器调用它。“Currying”将在这里为您提供帮助:给定

def criteriaCondition= grailsApplication.config.criteriaCondition?:{user->
         or{
           eq('username',user.username)
           eq('name',user.name)   
         }
}

而不是说

User.createCriteria().list{criteriaCondition(user)}

你说

User.createCriteria().list(criteriaCondition.curry(user))

(注意圆括号而不是大括号)。

curry方法Closure返回另一个,其Closure部分或全部参数“预先绑定”到特定值。例如

def add = {a, b -> a + b}
def twoPlus = add.curry(2) // gives a closure equivalent to {b -> 2 + b}
println twoPlus(3) // prints 5

在你的情况下,criteriaCondition.curry(user)给你一个零参数的闭包,你可以传递给criteria.list. 您可以根据需要使用任意数量的参数(直到闭包可以接受的数量)。

于 2013-09-19T10:28:41.160 回答