gpt4 book ai didi

grails - 在 Grails 中向域对象添加动态字段

转载 作者:行者123 更新时间:2023-12-02 14:34:50 25 4
gpt4 key购买 nike

我正在尝试找到一种将动态字段添加到 grails 域类的方法。我确实根据 Burt 的文章找到了动态域类插件,但这对我们的需求来说太过分了。

假设我们有一个域类 person:

class Person extends DynamicExtendableDomainObject {
String firstName
String lastName

static constraints = {
firstName(nullable: false, blank: false, maxSize: 50)
lastName(nullable: false, blank: false)
}
}

现在客户 一个 希望在此也有一个生日字段。通过使用某种管理工具,他在数据库中添加了这个额外的字段。

客户 b 还想有一个字段中间名,所以他正在为这个人添加字段中间名。

现在我们实现了 DynamicExtendableDomainObject类,Person 类继承自该类。这会为每个继承自此的 Domain 类添加一个自定义字段,以将动态属性存储为 JSON在其中(有点像 Perl 中的 KiokuDB 存储它们)。

现在当 Person 被实例化时,我们希望将这些动态属性添加到 Person 类中,以便能够使用标准 Grails getter 和 setter 以及用于这些的模板函数。

等等客户 一个 我们可以使用脚手架,人会输出名字、姓氏、出生日期,在客户 b 上,脚手架会输出名字、姓氏、中间名。

属性的存储将通过使用 saveinterceptor 来实现。 , 将这些属性序列化为 JSON 并将它们存储在特殊字段中。

但是我们还没有找到在运行时将这些 JSON 属性动态添加到域类的方法。有没有好的方法来处理这个?如果是这样,如何最好地实现这一点?

最佳答案

您可以尝试在运行时将属性添加到类型为 DynamicExtendableDomainObject 的 DomainClass通过在 metaClass 中扩展 getProperty()、setProperty()、setProperties(),然后使用 beforeUpdate()、beforeInsert() 和 afterLoad() 来 Hook 到 Persistence。

例如在 Bootstrap(或服务)中:

def yourDynamicFieldDefinitionService

for(GrailsClass c in grailsApplication.getDomainClasses()){
if(DynamicExtendableDomainObject.isAssignableFrom(c.clazz)){
Set extendedFields = yourDynamicFieldDefinitionService.getFieldsFor(c.clazz)

//getProperty()
c.clazz.metaClass.getProperty = { String propertyName ->
def result
if(extendedFields.contains(propertyName)){
result = delegate.getExtendedField(propertyName)
} else {
def metaProperty = c.clazz.metaClass.getMetaProperty(propertyName)
if(metaProperty) result = metaProperty.getProperty(delegate)
}
result
}

//setProperty()
c.clazz.metaClass.setProperty = { propertyName , propertyValue ->
if(extendedFields.contains(propertyName)){
delegate.setExtendedField(propertyName, propertyValue)
delegate.blobVersionNumber += 1
} else {
def metaProperty = c.clazz.metaClass.getMetaProperty(propertyName)
if(metaProperty) metaProperty.setProperty(delegate, propertyValue)
}
}

//setProperties()
def origSetProperties = c.clazz.metaClass.getMetaMethod('setProperties',List)
c.clazz.metaClass.setProperties = { def properties ->
for(String fieldName in extendedFields){
if(properties."${fieldName}"){
delegate."${fieldName}" = properties."${fieldName}"
}
}
origSetProperties.invoke(delegate,properties)
}
}
}


abstract DynamicExtendableDomainObject {
String yourBlobField
Long blobVersionNumber //field to signal hibernate that the instance is 'dirty'

Object getExtendedField(String fieldName){
...
}

void setExtendedField(String fieldName, Object value){
...
}

def afterLoad(){
//fill your transient storage to support getExtendedField + setExtendedField
}

def beforeUpdate(){
//serialize your transient storage to yourBlobField
}

def beforeInsert(){
//serialize your transient storage to yourBlobField
}
}

关于grails - 在 Grails 中向域对象添加动态字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15067352/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com