在我的任务管理应用程序中,用户应该能够根据以下内容过滤任务:assignedTo
,priority
,status
和/或dueDate
我不确定如何创建动态查询,因为它将根据可用参数构建查询。
例如:
如果我有以下网址:task/index?assignedTo=1&status=2
我可以仅基于这两个参数构建查询。我习惯的方法是
Task.findAllByAssignedToAndStatus(
User.get(params.assignedTo),
TaskStatus.get(params.status)
)
我显然不希望通过为每个可能的URL参数组合写出每个findAllBy
查询来实现DRY方法。
在grails中有一个很好的方法吗?
答案 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)
看看流畅的界面,您可以使用它们来添加或删除(过滤)每个参数。
答案 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