4

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

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

提前致谢

4

2 回答 2

1

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

尝试将您的代码更改为

  static namedQueries = {
      hasGenre {genreNameList -> 
            book{
               genres {  
              'in'  'title', genreNameList 
           } 
       }
   }
  }
于 2015-10-16T10:34:49.593 回答
1

条件查询和原生查询(如 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'...)。

于 2015-10-16T14:07:48.143 回答