Grails:在地图构造函数中设置瞬态字段

Posted

技术标签:

【中文标题】Grails:在地图构造函数中设置瞬态字段【英文标题】:Grails: setting transient fields in the map constructor 【发布时间】:2014-11-03 03:20:23 【问题描述】:

我正在尝试将属性映射保留为单个 JSON 编码列,如 this question 所示。

我遇到的问题是显然无法在默认地图构造函数中设置瞬态属性。给定任何瞬态字段:

class Test 
    //...
    String foo
    static transients = ['foo']

似乎 map 构造函数(Grails 以各种方式覆盖)只是丢弃了瞬态字段:

groovy:000> t = new Test(foo:'bar')
===> Test : (unsaved)
groovy:000> t.foo
===> null

虽然直接赋值(通过 setter 方法)按预期工作:

groovy:000> c.foo = 'bar'
===> bar
groovy:000> c.foo
===> bar

有没有办法让地图构造函数接受瞬态字段?


或者更确切地说:有没有更好的方法将Map 持久化为单个 JSON 编码的 DB 字段,而不是 linked question 中显示的方法?

这是完整的例子:

import grails.converters.JSON

class JsonMap 
    Map data
    String dataAsJSON

    static transients = ['data']
    def afterLoad()       data = JSON.parse(dataAsJSON) 
    def beforeValidate()  dataAsJSON = data as JSON 

我可以使用设置器设置data(然后将其转换为dataAsJSON),但不能使用地图构造函数。

【问题讨论】:

暂态属性不会被持久化。我认为这是不可能的。 我知道他们没有持久化。如果您阅读链接的问题,则 Map 属性是故意声明为瞬态的。 【参考方案1】:

GORM 中的 map 构造函数使用数据绑定机制,transient 属性默认是不可绑定的。但是您可以使用 bindable constraint

覆盖它
class Test 
    //...
    String foo
    static transients = ['foo']

    static constraints = 
        foo bindable:true
    

【讨论】:

这正是我想要的!谢谢【参考方案2】:

我也回复了你的original question,说你不需要json转换就可以实现你需要的。但是,如果你非常需要 json 转换,为什么不在你的 getter/setter 中实现呢?

class Test 
    String propsAsJson

    static transients = ['props']

    public Map getProps() 
        return JSON.parse(propsAsJson)
    

    public void setProps(Map props) 
        propsAsJson = props as JSON
    


//So you can do
Test t = new Test(props : ["foo" : "bar"])
t.save()

通过这种方式,您封装了转换的东西,并且在 DB 中您的属性为 Json。

【讨论】:

这不是每次修改属性时都会将数据转换为 Json 还是只在保存时转换?【参考方案3】:

您可以通过将 JSON 转换方法添加到您的域类来简化您的案例,它们应该与 GORMing 无关:

class Test 
    String title

    void titleFromJSON( json ) 
      title = json.toStringOfSomeKind()
    

    def titleAsJSON() 
      new JSON( title )
    


【讨论】:

这提供的功能比现有的 afterLoad / beforeValidate 方法少,并且没有解决使用 map 构造函数设置瞬态值的问题。

以上是关于Grails:在地图构造函数中设置瞬态字段的主要内容,如果未能解决你的问题,请参考以下文章

为啥枚举的构造函数不能访问静态字段?

在构造函数调用中设置一个短值[重复]

如何在构造函数中设置 GUI 不可见?

在“原型”中设置“构造函数”属性的好处

在构造函数中设置默认参数?语法[关闭]

PHP ORM如何在构造函数中设置id