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

时间:2013-04-11 11:23:02

标签: grails groovy gorm

在我的任务管理应用程序中,用户应该能够根据以下内容过滤任务:assignedToprioritystatus和/或dueDate

我不确定如何创建动态查询,因为它将根据可用参数构建查询。

例如:

如果我有以下网址:task/index?assignedTo=1&status=2

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

Task.findAllByAssignedToAndStatus(
   User.get(params.assignedTo),
   TaskStatus.get(params.status)
)

我显然不希望通过为每个可能的URL参数组合写出每个findAllBy查询来实现DRY方法。

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

5 个答案:

答案 0 :(得分: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
            }
        }

    }
}

这启用了细粒度的过滤器功能,因此您可以构建一个使用所有过滤器方法的列表方法,并根据用户提供的输入将命名查询连接在一起。

Employee.filteronFirstname("John").
filterOnLastname("Doe").
filteronAgeOlderThen("10").
list(params)

答案 1 :(得分: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
}

答案 2 :(得分:1)

我会考虑使用Searchable插件(http://grails.org/plugin/searchable)。可以很容易地指定Task的哪些属性应该是可搜索的。

答案 3 :(得分:0)

看看流畅的界面,您可以使用它们来添加或删除(过滤)每个参数。

http://en.wikipedia.org/wiki/Fluent_interface

答案 4 :(得分:0)

我对来自网址的动态Where查询的解决方案:

if (params.query) {
    def classLoader = getClass().getClassLoader();
    def query = new GroovyShell(classLoader).evaluate(
            "import myapp.Visit; Visit.where {$params.query}")
    visits = query.list(params)
} 

这会从这样的URL中获取约束:

visit/index?query=client.status=='suspect';atHome==false