Grails 命名查询不适用于 "in" 语句
Grails named queries not working with "in" statement
我有一个 Grails 应用程序 (2.2.4)。我在域 class 中的哪个地方看起来像这样
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 的书的作者
String comaSeperatedGenereName = "genere1,genere2"
def genereNameList = comaSeperatedGenereName.split(",")
Author.hasGenre(genereNameList)
但是如果我像下面这样更改 namedQuery,
hasGenre {genreName ->
book{
genres {
eq 'title' , genreName
}
}
如果我像下面这样传递一个字符串
Author.hasGenre('genere1')
这按预期工作。我有什么遗漏吗?
提前致谢
operator 中有一个 groovy,我怀疑你得到的不是标准中的 groovy in operator.
尝试将您的代码更改为
static namedQueries = {
hasGenre {genreNameList ->
book{
genres {
'in' 'title', genreNameList
}
}
}
}
条件查询和 SQL 等本机查询之间的细微差别是条件查询不是实际查询。这是一个查询 builder。
换句话说,条件查询在 运行 与 SQL 查询 运行 中的意义不同SQL 数据库。相反,执行标准查询以 生成 数据库查询。考虑到这一点,就更容易看出哪里出了问题。
hasGenre {genreNameList ->
book{
genres {
'title' in genreNameList
}
}
}
表达式 'title' in genreNameList
return 是一个布尔值。它对条件查询没有影响,因为 none 的条件查询的构建器方法被调用。所以最后查询构造为 return everything.
条件查询中 Groovy 关键字的等价物是 in()
方法。
hasGenre {genreNameList ->
book{
genres {
'in'('title', genreNameList)
}
}
}
这构建了您期望的查询。但是,因为 in
是 Groovy 中的关键字,为了执行该方法,必须引用其名称。我认为 aesthetically-pleasing 完成同样事情的方法是 inList()
方法。
hasGenre {genreNameList ->
book{
genres {
inList('title', genreNameList)
}
}
}
最后,为了更好地说明构建器的概念,这里有一个更详细的方法来完成同样的事情。
hasGenre {genreNameList ->
book{
genres {
or {
genreNameList.each {
eq('title', it)
}
}
}
}
}
此查询是通过为每个流派标题调用 eq()
构建的。最终结果是具有多个 或 连词的查询(例如 title = 'foo' 或 title = 'bar'...)。
我有一个 Grails 应用程序 (2.2.4)。我在域 class 中的哪个地方看起来像这样
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 的书的作者String comaSeperatedGenereName = "genere1,genere2"
def genereNameList = comaSeperatedGenereName.split(",")
Author.hasGenre(genereNameList)
但是如果我像下面这样更改 namedQuery,
hasGenre {genreName ->
book{
genres {
eq 'title' , genreName
}
}
如果我像下面这样传递一个字符串
Author.hasGenre('genere1')
这按预期工作。我有什么遗漏吗?
提前致谢
operator 中有一个 groovy,我怀疑你得到的不是标准中的 groovy in operator.
尝试将您的代码更改为
static namedQueries = {
hasGenre {genreNameList ->
book{
genres {
'in' 'title', genreNameList
}
}
}
}
条件查询和 SQL 等本机查询之间的细微差别是条件查询不是实际查询。这是一个查询 builder。
换句话说,条件查询在 运行 与 SQL 查询 运行 中的意义不同SQL 数据库。相反,执行标准查询以 生成 数据库查询。考虑到这一点,就更容易看出哪里出了问题。
hasGenre {genreNameList ->
book{
genres {
'title' in genreNameList
}
}
}
表达式 'title' in genreNameList
return 是一个布尔值。它对条件查询没有影响,因为 none 的条件查询的构建器方法被调用。所以最后查询构造为 return everything.
条件查询中 Groovy 关键字的等价物是 in()
方法。
hasGenre {genreNameList ->
book{
genres {
'in'('title', genreNameList)
}
}
}
这构建了您期望的查询。但是,因为 in
是 Groovy 中的关键字,为了执行该方法,必须引用其名称。我认为 aesthetically-pleasing 完成同样事情的方法是 inList()
方法。
hasGenre {genreNameList ->
book{
genres {
inList('title', genreNameList)
}
}
}
最后,为了更好地说明构建器的概念,这里有一个更详细的方法来完成同样的事情。
hasGenre {genreNameList ->
book{
genres {
or {
genreNameList.each {
eq('title', it)
}
}
}
}
}
此查询是通过为每个流派标题调用 eq()
构建的。最终结果是具有多个 或 连词的查询(例如 title = 'foo' 或 title = 'bar'...)。