基于传递给控制器​​的参数动态创建查询

and*_*ugh 5 grails groovy grails-orm

在我的任务管理应用程序,用户应该根据能够过滤任务:assignedTo,priority,status和/或dueDate

我不确定如何创建动态查询,因为它将基于可用参数构建查询.

例如 :

如果我有一个URL,例如: task/index?assignedTo=1&status=2

我可以仅基于这两个参数构建查询.我习惯的方法是

Task.findAllByAssignedToAndStatus(
   User.get(params.assignedTo),
   TaskStatus.get(params.status)
)
Run Code Online (Sandbox Code Playgroud)

我显然不希望落实写出每一个干法findAllBy查询每一个可能的URL参数组合.

在grails中有一个很好的方法吗?

Mar*_*rco 7

我们已经在域类上实现了过滤器功能来执行此操作.简而言之,您将namedQueries的小片段添加到您的域类中.

例:

class Employee {

    String firstname
    String lastname
    Integer age

    static constraints = {
    }

    static namedQueries = {
        filteronFirstname { String inFirstname ->
            if (inFirstname&& inFirstname?.size() > 0) {
                ilike 'firstname', "%${inFirstname}%"
            }
        }

        filteronLastname { String inLastname ->
            if (inLastname && inLastname?.size() > 0) {
                ilike 'lastname', "%${inLastname}%"
            }
        }

        filteronAgeOlderThen { String ageOlderThen ->
            if (age && age ?.size() > 0) {
                gt 'age', ageOlderThen as Integer
            }
        }

    }
}
Run Code Online (Sandbox Code Playgroud)

这样可以实现细粒度的过滤器功能,因此您可以构建一个使用所有过滤器方法的列表方法,并根据用户提供的输入将namedqueries连接在一起.

Employee.filteronFirstname("John").
filterOnLastname("Doe").
filteronAgeOlderThen("10").
list(params)
Run Code Online (Sandbox Code Playgroud)


and*_*ugh 5

我设法使用createCriteria如下工作:

如果用户为该特定过滤器选择"全部",则我对任何参数使用值0,因此它将从where子句中省略,即没有eq()该参数的语句.

一段代码:

else
    {       
        def assignedTo = Integer.parseInt(taskParams.assignedTo)
        def priority = Integer.parseInt(taskParams.priority)
        def status = Integer.parseInt(taskParams.status)

        tasks = Task.createCriteria().list {            

            eq("project", Project.get(taskParams.PId))

            if(assignedTo > 0)
                eq("assignedTo", User.get(assignedTo))

            if(priority > 0)
                eq("priority", TaskPriority.get(priority))

            if(status > 0)
                eq("status", TaskStatus.get(status))                
        }           
    }
    return tasks
}
Run Code Online (Sandbox Code Playgroud)