多个创建条件重用代码grails

多个创建条件重用代码grails,grails,gorm,Grails,Gorm,我有一个使用多个带分页的参数创建条件。 我面临的问题是,如果可以在中重复使用代码,那么为其他人创建完全不同的标准,而不必重复代码。 我指出,如果我有案例createcriteria,并且希望在案例2上执行相同的“过滤器”,则不必重复代码,统一两个createcriteria不是一个选项 例如,我面临的问题是,一个需要分页,另一个不需要分页,两者都需要访问不同的字段,因此唯一的选择是创建两个相同的创建条件(如果我没有遗漏某些内容)。 这是一个例子,cases与cases2之间至少有90%是独立的,

我有一个使用多个带分页的参数创建条件。 我面临的问题是,如果可以在中重复使用代码,那么为其他人创建完全不同的标准,而不必重复代码。 我指出,如果我有案例createcriteria,并且希望在案例2上执行相同的“过滤器”,则不必重复代码,统一两个createcriteria不是一个选项 例如,我面临的问题是,一个需要分页,另一个不需要分页,两者都需要访问不同的字段,因此唯一的选择是创建两个相同的创建条件(如果我没有遗漏某些内容)。 这是一个例子,cases与cases2之间至少有90%是独立的,那么什么是重用代码的好模式呢

 def cases = PpCase.createCriteria().list{ 
            and{
                if(limit){
                    maxResults(limit)
                }
                firstResult(offset)
                order("mostRecentPaymentDate", "desc")
                order("totalAmount", "desc")
                if(params.admin_id){
                    eq("adminId",params.admin_id)
                }
                if(params.status){
                    eq("status",params.status.toUpperCase() as PpCase.Status)
                }
                if(params.date_from){
                    ge('dateCreated', Date.parse("yyyy-MM-dd",params.date_from))
                }
                if(params.date_to){
                    le('dateCreated', Date.parse("yyyy-MM-dd",params.date_to))
                }
                if(params.date_closed_from){
                    ge('closedDate', Date.parse("yyyy-MM-dd",params.date_closed_from))
                }
                if(params.date_closed_to){
                    le('closedDate', Date.parse("yyyy-MM-dd",params.date_closed_to))
                }
        }
}

def cases2 = PpCase.createCriteria().list{ 
            and{
                firstResult(offset)
                order("mostRecentPaymentDate", "desc")
                order("totalAmount", "desc")
                if(params.admin_id){
                    eq("adminId",params.admin_id)
                }
                if(params.status){
                    eq("status",params.status.toUpperCase() as PpCase.Status)
                }
                if(params.date_from){
                    ge('dateCreated', Date.parse("yyyy-MM-dd",params.date_from))
                }
                if(params.date_to){
                    le('dateCreated', Date.parse("yyyy-MM-dd",params.date_to))
                }
                if(params.date_closed_from){
                    ge('closedDate', Date.parse("yyyy-MM-dd",params.date_closed_from))
                }
                if(params.date_closed_to){
                    le('closedDate', Date.parse("yyyy-MM-dd",params.date_closed_to))
                }
        }
}
更真实的例子: 如果我需要一些字段,但有一个限制,如果我需要不同的字段,并且没有限制,我会复制90%的代码

     def cases = PpCase.createCriteria().list{ 
                projections {
                    sum("field1")
                    countDistinct("id")
                }
              and{
               if(limit){
                    maxResults(limit)
                }
           //HERE SHOULD BE THE CODE THAT I NEED TO REUTILIZE
 }
 def cases2 = PpCase.createCriteria().list{ 
                projections {
                    sum("field2")
                    countDistinct("id")
                }
              and{

           //HERE SHOULD BE THE CODE THAT I NEED TO REUTILIZE
 }

您可以使用命名查询执行此操作:
请看一下文档。

我不确定您所说的“统一两个createCriteria不是一个选项”是什么意思,特别是考虑到在上面的代码中,您执行了两次完全相同的查询,最后得到了两个包含相同行的列表

重用标准的一种方法是将标准定义为单独的闭包,并将其传递给createCriteria

Closure fetchPayments = { 
        and{
            if(limit){
                maxResults(limit)
            }
            firstResult(offset)
            order("mostRecentPaymentDate", "desc")
            order("totalAmount", "desc")
            if(params.admin_id){
                eq("adminId",params.admin_id)
            }
            if(params.status){
                eq("status",params.status.toUpperCase() as PpCase.Status)
            }
            if(params.date_from){
                ge('dateCreated', Date.parse("yyyy-MM-dd",params.date_from))
            }
            if(params.date_to){
                le('dateCreated', Date.parse("yyyy-MM-dd",params.date_to))
            }
            if(params.date_closed_from){
                ge('closedDate', Date.parse("yyyy-MM-dd",params.date_closed_from))
            }
            if(params.date_closed_to){
                le('closedDate', Date.parse("yyyy-MM-dd",params.date_closed_to))
            }
    }
}

def cases  = PpCase.createCriteria().list(fetchPayments)
def cases2 = PpCase.createCriteria().list(fetchPayments)

我会使用,在引擎盖下使用
DetachedCriteria
,或者。其中查询只有在您调用
list
/
get
/
count
/
时才会运行,因此它们非常适合于将查询分解成部分。命名查询也可以类似地组合,但它们必须是完整的、可运行的查询,但如果在运行查询之前通过组合添加缺少的部分,则可以使用局部查询。它们也更灵活,因为您可以使用它们来删除和更新。

我会检查它,我会把答案再打开一点,看看我是否会得到另一个回复!是的,这个例子是相同的createCriteria来简化事情,但是代码有点不同,做不同的投影,需要重用的部分是createCriteria的条件和{}条件,我将上传一个更真实的例子添加的例子在这种情况下,它只是对原始答案的一个小改动;将单独定义的闭包保持为“fetchPayments”,只需将该闭包称为标准构建的一部分,您需要两个场景def cases=PpCase.createCriteria().list{delegate.with fetchPayments/*cases 1此处的特定条件/}def cases2=PpCase.createCriteria().list{delegate.with fetchPayments/此处的特定条件*/}是的,我现在正在测试它,我认为这应该行得通。我测试了def cases=PpCase.createCriteria().list(fetchPayments)和您引用并收到的fetchPayments groovy.lang.MissingPropertyException:无此类属性:类的限制:grails.orm.HibernateCriteriaBuilder将参数传递给clouse,我收到| groovy.lang.MissingMethodException:没有方法签名:webserver.PpCaseService.and()适用于参数类型:(webserver.PpCaseService$_closure1_closure12)和第二个选项以及PpCase.createCriteria().list{delegate.with{fetchPayments}}不抛出错误,但根本不起作用