在 Grails 控制器中重用 Criteria
通常,您在 Grails 生成的控制器列表方法中具有以下最后一行:
[userInstanceList: User.list(params), userInstanceTotal: User.count()]
如果我想通过特定条件限制用户,它看起来像,
[userInstanceList: User.list(params) {
ilike('login', '%test%')
}, userInstanceTotal: User.count() {
ilike('login', '%test%')
}]
但这违反了 DRY 原则 - 重用条件闭包的最佳方法是什么?
typically you have the following last line in a Grails generated Controller list method:
[userInstanceList: User.list(params), userInstanceTotal: User.count()]
if I want to restrict the users by a specific criteria it looks like
[userInstanceList: User.list(params) {
ilike('login', '%test%')
}, userInstanceTotal: User.count() {
ilike('login', '%test%')
}]
but this violates the DRY principle - what would be the best way to reuse the criteria closure?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
来自条件构建器的分页结果(结果类为 PagedResultList) 有一个属性
totalCount
,您可以像根据相同条件调用count()
一样使用该属性:Paged results from a criteria builder (the result class is PagedResultList) have a property,
totalCount
, which you can use just like you were callingcount()
on the same criteria:针对这种情况的另一种方法(需要在各种不同的条件查询中重用相同的逻辑)可能是使用常规闭包,正如您在帖子标题中所述。
使用 PagedResultList 的 TotalCount 属性可以更好地解决您的特殊情况,正如 Dana 在她的答案中发布的那样。但您可能会遇到更复杂的情况,您必须重用标准内的逻辑。对于类似的情况,我成功尝试了以下解决方案。仅以您的情况为例:
iLikeLoginClosure 中的 builder 是对调用闭包的标准构建器对象的引用。此外,在 iLikeLoginClosure 内部,您可以在定义的闭包中使用相同范围的变量。
这是受到这篇文章的启发:http://mrhaki。 blogspot.com.ar/2010/06/grails-goodness-refactoring-criteria.html 来自 MrHaki 的优秀博客。
Another approach for this situation (the need to reuse same logic inside various different criteria queries), could be the use of groovy closures, as you stated in the title of your post.
Your particular case is better solved using the totalCount property of the PagedResultList, just as Dana posted in her answer. But you may come in more complex scenario where you have to reuse logic inside criteria. For a similar situation, I've successfully tried the following solution. Using your case just as an example:
Where builder in iLikeLoginClosure is a reference to the criteria builder object within which the closure is called. Furthermore, inside the iLikeLoginClosure you can use variables of the same scope within the closure is defined.
This was inspired by this article: http://mrhaki.blogspot.com.ar/2010/06/grails-goodness-refactoring-criteria.html from MrHaki's excellent blog.
您可以使用命名查询。
在您的域类中:
在您的控制器中:
或者(我不是 100% 确定这会起作用,但请尝试一下。):
You can use named queries.
In your domain class:
In your controller:
Or (I'm not 100% sure this will work, but try it.):