Grails命名查询不使用“in”语句

时间:2015-10-16 05:53:09

标签: grails gorm named-query domain-object

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

这可以按预期工作。有什么我想念的吗?

提前致谢

2 个答案:

答案 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' ...)。