多个创建条件重用代码 grails

Multiple Create Criteria re-use code grails

我有一个使用带分页的多个参数的创建条件。 我遇到的问题是,如果可以重新使用完全不同的内部代码和其他创建条件,则无需复制代码。 我认为如果我有 cases createcriteria 并且想在 cases2 上做同样的事情 "filters" 而不必复制代码,统一两个 createCriteria 不是一个选项 例如,我面临的问题是一个需要分页,另一个不需要,并且都需要访问不同的字段,所以唯一的选择是创建两个相同的创建条件,如果我我没有遗漏什么。 这是一个例子,cases 至少有 90% 是 cases2,重用代码的好模式是什么?

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

更真实的例子: 在某些情况下,我需要一些字段,但有限制,而在 case2 中,我需要不同的字段,但没有限制,我将复制 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
 }

您可以使用命名查询来执行此操作: 查看文档。namedQueries

我不确定你所说的 "unify both createCriteria is not an option" 是什么意思,特别是考虑到在上面的代码中你执行了两次完全相同的查询并最终得到包含相同行的两个列表。

重用条件的一种方法是将条件定义为单独的闭包,并将其传递给 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)

我会使用 "where" queries, which use DetachedCriteria under the hood, or DetachedCriteria directly。在您调用 list/get/count/exists/deleteAll/updateAll 之前,查询不会 运行,因此它们非常适合分段组合查询。命名查询可以类似地组合,但它们需要完整,运行nable 查询,但部分 where 查询很好,只要您在 运行ning 之前通过组合添加缺少的部分。它们也更加灵活,因为您可以使用它们来删除和更新。