若想查询一个POJO类的部分属性,如

@Entity
class Captcha {
    String str
    String bak
    static constraints = {
        bak(nullable: true)
    }
}

若只想查询str,不查bak。可以通过HQL或Criteria指定要查询的字段。

如:

List<Object[]> list = Captcha.withCriteria {
    projections {
        property("id")
        property("str")
        property("version")
    }
    eq("id", 4L)
}

List<Object[]> list = Captcha.executeQuery("select id,str,version from Captcha")

注意这里返回的是对象数组,并非Domain对象。

如果要返回Domain对象也好办:

Captcha.executeQuery("select new Captcha(id,str,version) from Captcha"])

前提是Domain类必须有相应的构造函数:

Captcha(id, String str, version) {
    this.id = id
    this.str = str
    this.version = version
}

Criteria应该也可以返回Domain对象,偶现在还没找到方法,欢迎补充。

 

Hibernate更新时默认更新该类的所有属性。若想save时只更新部分属性需要额外的方法。

dynamicUpdate属性可以做到这一点,它默认是false:系统启动时预先生成sql。置为true可在运行期动态生成sql。

static mapping = {
    dynamicUpdate true
}
仅仅修改了该属性还不行,save时那些没有设置的字段:bak被置为null了。需要在设置属性值之前先锁定该对象,再修改,然后save。待事务提交之后自动解锁了。

        Captcha o = new Captcha(id: 4, str: "dsd", version: 4)
        Captcha.withTransaction {
            o.lock() //先上锁
            o.str += " modified "  //再修改值
            if (o.hasErrors() || !o.save(flush: true)) {  //然后save
                log.error(o.errors.toString())
            }
        } //事务提交后自动解锁了。

这样,持久化后数据库中bak字段仍是以前的值,没有被置为null。

检验下事务提交后是否自动解锁:

Captcha o = new Captcha(id: 4, str: "dsd", version: 4)
Captcha.withTransaction {
    o.lock() //先上锁
    o.str += " modified "
    if (o.hasErrors() || !o.save(flush: true)) {
        log.error(o.errors.toString())
    }
}
Captcha.withTransaction {
    o.str += " modified "// 未上锁
    if (o.hasErrors() || !o.save(flush: true)) {
        log.error(o.errors.toString())
    }
}

这样,bak字段在第二次save时被置为null了,可以进入数据库验证一下。