You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Grails 3.3中GORM CriteriaBuilder如何对属性调用函数?

嘿,这个问题我之前也踩过坑!CriteriaBuilder的eq方法默认会把第一个参数当成域类的属性名,而不是SQL函数调用,所以你直接写eq 'hour(registration)', 15肯定不会生效——它会傻呵呵地去找Student里叫hour(registration)的属性,当然找不到啦😅

下面给你两种不用改域类映射的优雅解决方案:

方法1:用GORM自带的function() API(优先推荐)

Grails 3.3的GORM CriteriaBuilder其实专门提供了function()方法来调用数据库函数,完全符合DSL风格,写法如下:

def c = Student.createCriteria()
def results = c.list {
    eq(function('hour', property('registration')), 15)
}
  • function('hour', ...):告诉GORM你要调用数据库的hour函数
  • property('registration'):把域类的registration字段作为函数参数传进去
  • 这种方式是GORM抽象层支持的,比直接写SQL更干净,要是以后换数据库(比如从MySQL转PostgreSQL),只要函数名一致就能直接用,不用改代码。

方法2:用sqlRestriction写原生SQL片段

如果需要更复杂的SQL逻辑,或者数据库函数名比较特殊,可以直接用sqlRestriction注入原生过滤条件:

def c = Student.createCriteria()
def results = c.list {
    sqlRestriction "hour(registration) = ?", [15]
}
  • 第一个参数是SQL条件片段,?是安全的占位符,第二个参数是对应的值(防止SQL注入)
  • 注意哦,不同数据库的小时提取函数可能不一样,比如Oracle要用EXTRACT(HOUR FROM registration),所以这种方式要考虑数据库兼容性。

为啥原来的写法不行?

再给你捋清楚原因:where查询的DSL有专门的函数解析逻辑,能识别hour(registration)是函数调用;但CriteriaBuilder的eq方法默认只认属性名,它会把hour(registration)当成一个属性的名字,自然查不到任何结果啦。

内容的提问来源于stack exchange,提问作者MonetsChemist

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:23:32