在 Grails 控制器中重用 Criteria

发布于 2024-10-19 03:42:33 字数 369 浏览 1 评论 0原文

通常,您在 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

神经大条 2024-10-26 03:42:33

来自条件构建器的分页结果(结果类为 PagedResultList) 有一个属性 totalCount,您可以像根据相同条件调用 count() 一样使用该属性:

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

Paged results from a criteria builder (the result class is PagedResultList) have a property, totalCount, which you can use just like you were calling count() on the same criteria:

def userInstanceList = User.createCriteria().list(params) {
    ilike 'login', '%test%'
}
[userInstanceList: userInstanceList, userInstanceTotal: userInstanceList.totalCount]
┼── 2024-10-26 03:42:33

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

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

def iLikeLoginClosure = { builder ->
    builder.ilike('login', '%test%')
}
[
    userInstanceList: User.list(params) {
        iLikeLoginClosure delegate
    },
    userInstanceTotal: User.count() {
        iLikeLoginClosure delegate
    }
]

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:

def iLikeLoginClosure = { builder ->
    builder.ilike('login', '%test%')
}
[
    userInstanceList: User.list(params) {
        iLikeLoginClosure delegate
    },
    userInstanceTotal: User.count() {
        iLikeLoginClosure delegate
    }
]

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.

溇涏 2024-10-26 03:42:33

您可以使用命名查询

在您的域类中:

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()

You can use named queries.

In your domain class:

static namedQueries = {
    ilikeLogin{login->ilike('login', "%$login%")}
}

In your controller:

def userList = User.ilikeLogin('test').list(params)
def usersCount= User.ilikeLogin('test').count()

Or (I'm not 100% sure this will work, but try it.):

def query = User.ilikeLogin('test')
def userList = query.list(params)
def usersCount= query.count()
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文