5

在我的任务管理应用程序中,用户应该能够根据 : assignedToprioritystatus/或dueDate

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

例如 :

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

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

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

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

在 grails 中有没有好的方法来做到这一点?

4

5 回答 5

7

我们已经在域类上实现了过滤器功能来做到这一点。简而言之,您将命名查询的小片段添加到您的域类中。

例子:

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

    }
}

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

Employee.filteronFirstname("John").
filterOnLastname("Doe").
filteronAgeOlderThen("10").
list(params)
于 2013-04-11T17:05:05.093 回答
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
}
于 2013-04-11T14:04:02.797 回答
1

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

于 2013-04-11T11:29:18.277 回答
0

看看 fluent 接口,您可以使用它们来添加或删除(过滤)每个参数。

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

于 2013-04-11T16:12:29.330 回答
0

我对来自 URL 的动态 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
于 2014-05-14T15:09:54.473 回答