通常,Grails生成的Controller列表方法中有以下最后一行:
[userInstanceList: User.list(params), userInstanceTotal: User.count()]
如果我想按照特定条件限制用户,则
[userInstanceList: User.list(params) {
ilike('login', '%test%')
}, userInstanceTotal: User.count() {
ilike('login', '%test%')
}]
但是这违反了DRY原则 - 重用标准闭包的最佳方法是什么?
答案 0 :(得分:5)
条件构建器的分页结果(结果类为PagedResultList)具有属性totalCount
,您可以像使用相同条件调用count()
一样使用该属性:< / p>
def userInstanceList = User.createCriteria().list(params) {
ilike 'login', '%test%'
}
[userInstanceList: userInstanceList, userInstanceTotal: userInstanceList.totalCount]
答案 1 :(得分:3)
针对这种情况的另一种方法(需要在各种不同的标准查询中重用相同的逻辑),可能是使用groovy闭包,正如您在帖子标题中所述。
使用PagedResultList的totalCount属性可以更好地解决您的特定情况,就像Dana在她的回答中所说的那样。但是,您可能会遇到更复杂的情况,您必须在标准内重用逻辑。对于类似的情况,我已经成功尝试了以下解决方案。以您的案例为例:
def iLikeLoginClosure = { builder ->
builder.ilike('login', '%test%')
}
[
userInstanceList: User.list(params) {
iLikeLoginClosure delegate
},
userInstanceTotal: User.count() {
iLikeLoginClosure delegate
}
]
iLikeLoginClosure 中的构建器是对其中调用闭包的条件构建器对象的引用。此外,在iLikeLoginClosure内部,您可以使用闭包内相同范围的变量定义。
这是受到这篇文章的启发:来自MrHaki优秀博客的http://mrhaki.blogspot.com.ar/2010/06/grails-goodness-refactoring-criteria.html。
答案 2 :(得分:2)
您可以使用named queries。
在您的域类中:
static namedQueries = {
ilikeLogin{login->ilike('login', "%$login%")}
}
在您的控制器中:
def userList = User.ilikeLogin('test').list(params)
def usersCount= User.ilikeLogin('test').count()
或者(我不是100%肯定会这样,但试试吧。):
def query = User.ilikeLogin('test')
def userList = query.list(params)
def usersCount= query.count()