过滤过滤的数据

时间:2012-01-29 16:50:46

标签: grails filtering criteria gorm

我是grails和MVC的新手所以请耐心等待。

我的GSP上有一些链接可以进行静态过滤。例如,下面的示例仅返回
那些状态为 打开 Request域类实例。但我也希望能够在同一模型上进行一些动态过滤(下面的代码中的 结果 )。

用例将是这样的:用户可以看到表中的所有Request域类实例。他点击了 打开请求 链接,只获得了 状态 属性的Request个实例值 打开 。他使用日期选择器控件设置dateFromdateTo并点击 过滤器 按钮,该按钮调用进一步过滤来自数据的方法/操作表。所以它应该只返回那些打开并在指定时间内创建的请求。

def openedRequests = {
    def contact = Contact?.findByUser(springSecurityService.currentUser)
    def productlines = contact.productlines()
    def requestCriteria = Request.createCriteria()      
    def results = requestCriteria.list {
        eq("status", "Open")
        and {
            'in'("productline",productlines)
        }

    }
    render(view:'supportList', model:[requestInstanceList:results, requestInstanceTotal: results.totalCount])
}

修改 的 在我的GSP上,我有几个调用控制器动作的链接,这些动作执行一些域类实例过滤。例如,我有OpenedRequests,ClosedRequests,NewRequests。但我也有一些文本框,组合框,datePicker控件用于额外的过滤。我用一个按钮调用filterRequests动作。

def filterRequests = {
    def contact = Contact?.findByUser(springSecurityService.currentUser)
    def productlines = contact.productlines()
    def requestCriteria = Request.createCriteria()
    def results = requestCriteria.list {
        if(params.fDateFrom && params.fDateTo){
            def dateFrom = new SimpleDateFormat("dd.MM.yyyy").parse(params.fDateFrom_value)
            def dateTo = new SimpleDateFormat("dd.MM.yyyy").parse(params.fDateTo_value)
            between("dateCreated",dateFrom,dateTo)
        }
        if(params?.fStatus){
            eq("status",params.fStatus)
        }
        if(params?.fCompany){
            eq("company", params.fCompany)
        }
        and {'in'("productline",productlines)
        }
        if(params.sort != null && params.order !=  null){
            order(params.sort, params.order)
        }
    }
    render(view:'supportList', model:[requestInstanceList:results, requestInstanceTotal: results.totalCount])

}

我希望能够使用一些提到的链接过滤Request实例,而不是设置一些额外的过滤器,例如dateFrom i dateTo with datePicker。我希望这些过滤器知道以前使用链接进行过滤,如果有的话。这样做的正确方法是什么?

2 个答案:

答案 0 :(得分:0)

您可以使用Grails 2.0中引入的DetachedCriterias

DetachedCriteria与任何会话无关,可以轻松重复使用:

def openRequests = new DetachedCriteria(Request).build {
     eq("status", "Open")
     and {
        'in'("productline",productlines)
     }
}

然后,根据您的下一个子过滤器请求,您可以重复使用DetachedCriteria并对其执行子查询,例如:

def results = openRequests.findByStartDateBetweenAndEndDateBetween(dateFrom, dateTo, dateFrom, dateTo)

当然,您必须以某种方式记住原始查询(会话,请求参数),使用正确的标准作为子查询的基础。

(免责声明:我自己还没有尝试过独立标准)

答案 1 :(得分:0)

David建议我使用Detached Criteria但我使用Grails 1.3.7作为我的应用程序。所以,目前这不是一个选择。我还想过使用数据库视图和存储过程,但我不确定它将如何与Grails一起使用(但这是我必须要探索的东西)并且我想快速得到一些结果,所以我做了一些不太干的事情。当我使用上面提到的链接之一过滤表时,我在会话和filterRequest操作中保存链接/操作的名称(进行额外的过滤)我检查会话以查看是否有任何先前的“链接过滤”,如果它如果我使用标准在表格上应用这些过滤器,然后我应用手动输入的过滤器。我不喜欢它,但这是我对Grails的有限理解而想到的。以下是我的filterRequest操作:

def filterRequests = {
    def contact = Contact?.findByUser(springSecurityService.currentUser)
    def productlines = contact.productlines()
    def requestCriteria = Request.createCriteria()
    def results = requestCriteria.list {
        if(session.filter == "newRequests"){
            and{
                isNull("acceptedBy")
                ne("status", "Closed")
            }
        }
        if(session.filter == "openRequests"){
            and{
                ne("status",'Closed')
            }
        }
        if(session.filter == "closedRequests"){
            and{
                eq("status", "Closed")
            }
        }   

        if(session.filter == "myRequests"){
            and{
                eq("acceptedBy", contact.realname)
            }
        }


        if(params.fDateFrom && params.fDateTo){
            def dateFrom = new SimpleDateFormat("dd.MM.yyyy").parse(params.fDateFrom_value)
            def dateTo = new SimpleDateFormat("dd.MM.yyyy").parse(params.fDateTo_value)
            and{
                between("dateCreated",dateFrom,dateTo)
            }
        }
        if(params?.fAcceptedBy){
            and{
                eq("acceptedBy", params.fAcceptedBy)
            }
        }
        if(params?.fStartedBy){
            and{
                eq("startedBy", params.fStartedBy)
            }
        }
        if(params?.fCompany){
            and{
                ilike("company", "%" + params.fCompany +"%")
            }   
        }
        and {'in'("productline",productlines)
        }
        if(params.sort != null && params.order !=  null){
            order(params.sort, params.order)
        }
    }
}