在createCriteria中使用属性值

时间:2013-05-10 17:46:55

标签: mysql grails jodatime

我有2个域类,项目和制造商。制造商在其上有一个属性,用于在项即将到期时警告用户(其日期存储为Joda DateTime对象)。相关字段设置如下。

class Manufacturer {
    Integer expirationWarning

    static hasMany = [items: Item]
}

class Item {
    DateTime expirationDate

    static belongsTo = [manufacturer: Manufacturer]
}

我正在尝试创建一个项目列表,其中到期时间是从现在到现在加上到期警告天数。我已经在MySQL终端中正确地运行了查询。

SELECT i.id FROM items as i 
   LEFT JOIN (manufacturer as m) ON (m.id = i.manufacturer_id) 
   WHERE i.expiration_date <= DATE_ADD(current_date, INTERVAL m.expiration_warning DAY);

现在我只需要在Grails中执行相同的查询。我知道createCriteria看起来像这样:

def itemsExpiringSoon = Item.createCriteria().list(max: listMax, offset: params.offset) {
    createAlias('manufacturer', 'm', CriteriaSpecification.LEFT_JOIN)
    le('expirationDate', new DateTime().plusDays('m.expirationWarning'))
    order('expirationDate', 'desc')
}

但是为了在DateTime.plusDays()中使用该字段的值,我无法弄清楚应该用什么代替'm.expirationWarning'。对此的任何指导都将非常有用。

2 个答案:

答案 0 :(得分:1)

您不能以这种方式混合查询,但条件可以选择直接添加sql,然后您可以使用date_add()

def itemsExpiringSoon = Item.createCriteria().list(max: listMax, offset: params.offset) {
    createAlias('manufacturer', 'm', CriteriaSpecification.LEFT_JOIN)
    sqlRestriction('m.expiration_warning <= DATE_ADD(current_date, INTERVAL m.expiration_warning DAY)')
    order('expirationDate', 'desc')
}

请注意,在sqlRestriction()中,您编写了将在最终SQL中添加的内容,因此我们使用数据库列的名称,而不是域类的属性。

答案 1 :(得分:0)

两年半之后,我终于找到了解决这个问题的方法。

我创建的实际上是我应用GORM公式的瞬态属性,它表示当前日期加上制造商指定的到期警告。

class Item {
    Date expirationDate
    Date pendingExpiration

    static belongsTo = [manufacturer: Manufacturer]
    static mapping = {
         pendingExpiration formula: "(SELECT ADDDATE(current_date, mfr.expiration_warning) FROM manufacurer mfr WHERE mfr.id = manufacturer_id LIMIT 1)"
    }
}

现在我可以查询此属性,它将像Manufacturer.expirationWarning一样动态更新。