Grails 命名查询不适用于"in"语句



我有一个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

中至少有一本具有genere的书的Authors值
String comaSeperatedGenereName = "genere1,genere2"
def genereNameList = comaSeperatedGenereName.split(",")
Author.hasGenre(genereNameList)

但是如果我像下面这样改变namedQuery,

      hasGenre {genreName -> 
            book{
               genres {  
                   eq 'title' , genreName 
           } 
       }

如果我传递一个像这样的字符串

Author.hasGenre('genere1')

按预期工作。我是不是漏掉了什么?

Thanks in advance

有一个groovy in操作符,我怀疑你得到的不是标准,而是groovy in操作符。

尝试将代码更改为

  static namedQueries = {
      hasGenre {genreNameList -> 
            book{
               genres {  
              'in'  'title', genreNameList 
           } 
       }
   }
  }

标准查询和本地查询(如SQL)之间的细微差别是,标准查询不是实际的查询。它是一个查询生成器

换句话说,标准查询不像在SQL数据库中运行SQL查询那样运行。相反,执行一个标准查询以生成一个数据库查询。考虑到这一点,就更容易看出哪里出了问题。

hasGenre {genreNameList -> 
    book{
       genres {  
           'title' in genreNameList 
       }
   } 
}

表达式'title' in genreNameList返回一个布尔值。它对标准查询没有影响,因为没有调用任何标准查询的构建器方法。因此,最后构造的查询将返回所有内容。

在标准查询中,与Groovy的in关键字等价的是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'…)。

相关内容

  • 没有找到相关文章

最新更新