Grails控制器中的重用标准

Grails控制器中的重用标准,grails,closures,criteria,Grails,Closures,Criteria,通常,Grails生成的控制器列表方法中有以下最后一行: [userInstanceList: User.list(params), userInstanceTotal: User.count()] 如果我想用一个特定的标准来限制用户,它看起来像 [userInstanceList: User.list(params) { ilike('login', '%test%') }, userInstanceTotal: User.count() { ilike('login', '%

通常,Grails生成的控制器列表方法中有以下最后一行:

[userInstanceList: User.list(params), userInstanceTotal: User.count()]
如果我想用一个特定的标准来限制用户,它看起来像

[userInstanceList: User.list(params) {
   ilike('login', '%test%')
 }, userInstanceTotal: User.count() {
   ilike('login', '%test%')
 }]
但这违反了DRY原则——重用criteria闭包的最佳方法是什么?

您可以使用

在您的域类中:

static namedQueries = {
    ilikeLogin{login->ilike('login', "%$login%")}
}
在控制器中:

def userList = User.ilikeLogin('test').list(params)
def usersCount= User.ilikeLogin('test').count()
或者(我不是100%确定这会起作用,但试试看):


来自条件生成器的分页结果(结果类为)有一个属性,
totalCount
,您可以使用该属性,就像在相同条件下调用
count()

def userInstanceList = User.createCriteria().list(params) {
    ilike 'login', '%test%'
}
[userInstanceList: userInstanceList, userInstanceTotal: userInstanceList.totalCount]

针对这种情况的另一种方法(需要在各种不同的条件查询中重用相同的逻辑)可能是使用groovy闭包,正如您在文章标题中所述

使用PagedResultList的totalCount属性可以更好地解决您的特殊情况,正如Dana在她的答案中所发布的那样。但在更复杂的场景中,您可能需要在标准中重用逻辑。对于类似的情况,我成功地尝试了以下解决方案。以您的案例为例:

def iLikeLoginClosure = { builder ->
    builder.ilike('login', '%test%')
}
[
    userInstanceList: User.list(params) {
        iLikeLoginClosure delegate
    },
    userInstanceTotal: User.count() {
        iLikeLoginClosure delegate
    }
]
其中,iLikeLoginClosure中的builder是对在其中调用闭包的条件生成器对象的引用。此外,在iLikeLoginClosure中,定义了可以在闭包中使用相同范围的变量


这篇文章的灵感来源于哈基先生的优秀博客。

这应该是公认的答案。使用
PagedResultList
确实是一个很棒的技巧!
def iLikeLoginClosure = { builder ->
    builder.ilike('login', '%test%')
}
[
    userInstanceList: User.list(params) {
        iLikeLoginClosure delegate
    },
    userInstanceTotal: User.count() {
        iLikeLoginClosure delegate
    }
]