我有一个Grails应用程序(2.2.4)。我在域类中的位置看起来像这样
class Author implements Serializable {
....
static hasMany = [
book : Book
]
static namedQueries = {
hasGenre {genreNameList ->
book{
genres {
'title' in genreNameList
}
}
}
}
}
class Book implements Serializable{
Author author
Genres genres
static belongsTo = [author: Author , genre: Genres ]
static mapping = {
.....
author lazy: false
}
}
class Genres implements Serializable{
String title
}
如果我按如下方式运行查询,则会检索所有值,而不仅仅是具有genereNameList中至少有一本书的作者的作者
String comaSeperatedGenereName = "genere1,genere2"
def genereNameList = comaSeperatedGenereName.split(",")
Author.hasGenre(genereNameList)
但是如果我像下面这样改变了namedQuery,
hasGenre {genreName ->
book{
genres {
eq 'title' , genreName
}
}
如果我传递一个像下面这样的字符串
Author.hasGenre('genere1')
这可以按预期工作。有什么我想念的吗?
提前致谢
答案 0 :(得分:1)
在操作员中有一个常规,我怀疑你在操作员身上得到了groovy而不是标准。
尝试将代码更改为
static namedQueries = {
hasGenre {genreNameList ->
book{
genres {
'in' 'title', genreNameList
}
}
}
}
答案 1 :(得分:1)
条件查询与SQL等本机查询之间的细微差别是条件查询不是实际查询。这是一个查询builder。
换句话说,条件查询不会运行与SQL查询在SQL数据库中运行的意义相同。而是执行标准查询以生成数据库查询。考虑到这一点,它更容易看出出了什么问题。
hasGenre {genreNameList ->
book{
genres {
'title' in genreNameList
}
}
}
表达式'title' in genreNameList
返回一个布尔值。它对条件查询没有影响,因为没有调用条件查询的构建器方法。所以最后构造查询以返回所有内容。
条件查询中关键字中Groovy的等价物是in()
方法。
hasGenre {genreNameList ->
book{
genres {
'in'('title', genreNameList)
}
}
}
这构建了您期望的查询。但是,因为in
是Groovy中的关键字,所以为了执行该方法,必须引用其名称。我认为一种更美观的方式来完成同样的事情是inList()
方法。
hasGenre {genreNameList ->
book{
genres {
inList('title', genreNameList)
}
}
}
最后,为了更好地说明构建者的概念,这里有一个更冗长的方法来完成同样的事情。
hasGenre {genreNameList ->
book{
genres {
or {
genreNameList.each {
eq('title', it)
}
}
}
}
}
通过为每个流派标题调用eq()
来构建此查询。最终结果是包含多个或连词的查询(例如title =' foo'或title =' bar' ...)。