Grails:如何通过命名查询和附加条件关闭来获取单个项目

时间:2014-09-04 17:59:21

标签: grails criteria

我正在使用Grails 2.4.3并且在命名查询时遇到问题。

例如我有这个

class Product {
   Customer customer
   ...
   static namedQueries = {
       byCustomer { Customer c ->
           eq('customer', c)
       }
   }
   ...
}   

现在我可以做到

Product.byCustomer(customer).list()

我的活动可以做到

Product.byCustomer(customer).list(pagination + sorting ) {
    ... 
    gt('price', 23.5)
}

如果我想要一个带有标准的gorm中的单个对象,我通常会这样做

Product.createCriteria().get {
   ....
   eq('name', 'foo')
}

这将返回名为=='foo'

的第一个匹配产品

现在,我想做的是:

Product.byCustomer(customer).get {
    ...
    eq('type', 'bar')
}

这给了我:

You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server       
version for the right syntax to use near 'from product this_)' at line 1. Stacktrace follows:
com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; 
check the manual that corresponds to your MariaDB server version for the right syntax to use near 
'from product this_)' at line 1

我也试过这个:

Product.byCustomer(customer) {
    ...
    eq('type', 'bar')
}.get()

也不起作用,因为byCustomer(...)返回一个集合。

我在这里想念什么?我真的很想知道所有其他方法似乎都有效,除了.get():

Product.byCustomer(customer).count {
    ...
    eq('type', 'bar')
} 

(这是有效的)

我非常感谢任何帮助。谢谢!

更新:

如前所述,如果您只想查询一组固定的属性,可以给出几个选项:

使用where子句:

Product.byCustomer(customer).findWhere([type: 'bar'])    

使用另一个名为“type”的查询

Product.byCustomer(customer).byType('bar').get()

问题:我想要添加一组动态标准 - 并且无法为我的域类中的所有属性创建命名查询。

更新2:

示例我希望根据条件按标准动态构建:

Product p = Product.byCustomer(customer).get() {

        if (condition) {
            eq('a', params.int('bar'))
            gt('b', params.int('foo'))
            items {
                eq('c', 'baz')
            }
        } else {

            ...

        }
    }

ANSWER

我想我发现这对我有用。因为我使用Grails> 2.0我可以使用 where-queries将返回DetachedCriteria

DetachedCriteria缺少get()方法,我甚至可以将findWhere - 类似语法与构建器语法混合使用 - 请查看:

Product.where { foo == '5' && bar > 8 }.get()

或者

Product.where { foo == '5' && bar > 8 }.build {
    items { 
        eq('baz', 5)
    }
}.get()

在两个闭包中(+ build)我可以动态添加条件。

现在是最后一部分 - 重用上面Query中已存在的namedQueries

Product.where { foo == '5' && bar > 8 }.build {
    items { 
        eq('baz', 5)
    }

    Product.byCustomer(customer)
}.get()

甜!不幸的是我还不能回答我自己的问题:)

更新

最后一部分不起作用。如何混合DetachedCriteria和命名查询?

1 个答案:

答案 0 :(得分:1)

由于带有闭包参数的命名查询的结果是java.util.ArrayList,您应该能够做到

Product.byCustomer(customer){
    ...
    eq('type', 'bar')
}.getAt(0)

如果结果为空列表,则返回null,否则返回第一个条目(在您的情况下是唯一的条目)。尝试使用Grails 2.4.3。