Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/mongodb/12.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mongodb 抽象父类需要子类的类变量_Mongodb_Inheritance_Groovy_Abstract Class - Fatal编程技术网

Mongodb 抽象父类需要子类的类变量

Mongodb 抽象父类需要子类的类变量,mongodb,inheritance,groovy,abstract-class,Mongodb,Inheritance,Groovy,Abstract Class,我是Groovy新手,正在尝试从Python跳转。不幸的是,我对Java一窍不通。我正在开发一个将MongoDB用作后端的程序,并编写了一个抽象域类来处理访问数据库的细节。文档内容是根据实例的属性动态生成的 import Database.Server abstract class Domain { ObjectId _id String comment Date created Date updated Boolean dirty=false

我是Groovy新手,正在尝试从Python跳转。不幸的是,我对Java一窍不通。我正在开发一个将MongoDB用作后端的程序,并编写了一个抽象域类来处理访问数据库的细节。文档内容是根据实例的属性动态生成的

import Database.Server

abstract class Domain {

    ObjectId _id
    String comment
    Date created
    Date updated
    Boolean dirty=false

    static findOne(Map query=[:]) {
        newInstance( collection().findOne(query as BasicDBObject) )
    }

    static find(Map query=[:]) {
        def cursor = collection().find( query as BasicDBObject )
        cursor.collect { doc -> newInstance(doc) }
    }

    static collection() {
        //todo catch error if db hasn't been selected yet.
        def db = Server.getDB()
        return db.getCollection(this.collectionName)
    }

    static count() {
        return collection().getCount()
    }

    def fields() {
        // get all properties of the object and remove the ones we don't want to have in the collection
        Map fieldMap = properties
        ['class', 'collectionName', 'dirty'].each { fieldMap.remove(it) }
        return fieldMap
    }

    void insert() {
        //todo incorporate audit trail
        this.created = new Date()
        this.updated = new Date()
        collection().insert( fields() as BasicDBObject )
        this.dirty = false
    }

    void save() {
        // todo incorporate audit trail
        this.updated = new Date()
        collection().save( fields() as BasicDBObject )
        this.dirty = false
    }

    String toString() {
        return "${collectionName}: " + fields().collect { "\n\t$it" }
    }
}
因此,我认为我可以通过对抽象类进行子类化并定义集合的名称来生成一个简单集合,如下所示:

class Test extends Domain { 
    static String collectionName = 'test'
}
但是,这不起作用。域中定义的方法无法查看测试中定义的collectionName变量。如何让Domain.collection()使用子类中定义的变量?这在Python中起作用,所有内容都被转储到实例的dict

如果您能告诉我如何覆盖属性设置操作符,以便设置参数将自动设置dirty=true,则会获得额外的积分


感谢您的帮助。

Groovy和Java没有任何类型的静态类成员继承。当您在名为
Domain
的groovy类中说
this.collectionName
时,您引用的是
Domain.collectionName
,即使您是通过类似
Test.collection()
的子类调用该方法

即使如此,您也可以通过一点元编程魔法来实现类似的效果。您可以在运行时添加静态方法,通过正确的类解析静态属性。不幸的是,它并不像python那样简单。下面是一个小例子:

class DomainHelper {
    static collection(collectionName) {
        def db = Server.getDB()
        return db.getCollection(collectionName)
    }
    static apply(domainClass) {
        domainClass.metaClass.'static'.collection = this.&collection.curry(domainClass.collectionName)
    }
}
class Test {
    static collectionName = "test"
}
DomainHelper.apply(Test)
Test.collection()

谢谢你的建议。使用categories或@Category/@Mixin对是否可以实现这一点?另外,我应该把
DomainHelper.apply(Test)
放在哪里?如果我把它放在定义新域的文件中,它不会被封装在一个脚本类中而不是实际执行吗?我最初的想法是使用mixin,但我找不到从mixin类中访问目标类的类的方法。可以在测试中的静态初始化块中调用apply方法(例如,
类测试{static{DomainHelper.apply(this)}…}
)。