npm-install camo

camo是针对Node.js和MongoDB的对象模型mapper(object document mapper)(ODM)

可以喝Mongoose ODM互换,但是和其有显著的不同

文章主要关注了Mongo ODMs新增的ES6特性,这些特性将不支持例如classes 和 schema 继承等特性

对于其他语言学习者(例如java),基于类的ODMs他们更加熟悉,因为可以很方便的声明一个基本模块,然后继承此模块。 Mongoose模型的继承性比较差,所以camo中基于类的继承是一个受欢迎的特性。

 

当我在使用Mongoose的时候,我嫉妒SQL使用者可以使用SQLite来替代更大的类似MySQL或者PostgreSQL一样的数据库。 SQLite是一个轻量级的数据库,用户可以使用一个简单的文件作为后端(backend),所以就木有必要下载和安装300MB+(Mac OSX 压缩版本)MySQL到你的电脑中来运行数据库操作。

此外,MongoDB还有一个越发流行的NeDB,这将存储数据到一个单一的文件(或者内存中),且针对Node.js Mongo Driver有一个相同的API。

 

和Mongoose不同的是,Camo 支持 NeDB 作为后端(backend),所以你不需要安装所有的MongoDB数据库,如果你不想安装的话。这对开发和测试提供了很大便利,因为其减少了本地依赖(local dependencies) 且让你的应用程序更加便携——NeDB是一个你可以从NPM简单安装的包。 所以只要你想要,你完全可以在创建产品初始阶段使用NeDB作为数据库,之后再将其扩大成一个完整的Mongo 数据库如果你的数据负载量增大。

 

连接到数据库

为了支持不同的数据库后端(database backends),camo通过一个URL字符串来了解从哪里以及怎样连接到你的数据库。如下例:

***javascript
var connect = require('camo').connect;

// Local Mongo database
connect('mongodb://localhost/camo_test').then(function(db) {
	// ...
});

// NeDB takes a directory path...
connect('nedb:///Users/scott/data/animals').then(function(db) {
	// ...
});

// ...or 'memory' for storing data in-memory
connect('nedb://memory').then(function(db) {
	// ...
});
```

一旦你连接到数据库,你可以开始创建并且保存你的模型(models)

 

创建你自己的模型

创建一个模型,你要做的就是扩展(extend)文档类型(the 'Document' class)并且具体化你的模式(schema)。给你可以覆盖的‘ static collectionName()’方法命名,且返回任何你想要的名称;或者,如果你不想要指定一个特定的名字,camo将会使用c类名且增加一个s到名字的末尾让其变成复数形式。

 

***javascript
var Document = require('camo').Document;

class User extends Document {
    constructor() {
        super();

        this.email = {
            type: String,
            unique: true
        };
        this.password = String;
        this.firstName = String;
        this.lastName = String;
        this.age = Number;
        this.created = {
            type: Date,
            default: Date.now
        };
        this.previousLogins = [Date];
    }

    static collectionName() {
        return 'users';
    }
}

 

上面我们申明了‘User’对象,这个对象包含了典型的用户数据,比如email,密码和姓名。你可能主语到声明schema的构造器使用了内置的JavaScript对象比如‘String’,'Number'和‘Date’。任何没有使用下划线作为前缀来声明的内容都包含在这个schema中。

 

在这些模型类中你可以使用所有典型的类特性,比如getters/setters,静态方法等等

***javascript
var Document = require('camo').Document;

class User extends Document {
    constructor() {
        super();

        // User schema here...
    }

    get fullName() {
        return this.firstName + ' ' + this.lastName;
    }

    canVote() {
        return this.age >= 18;
    }

    static getVoters() {
        return User.loadMany({ age: { $gte: 18 } });
    }
}

虽然ES6中的类语法只是一个糖衣语法(syntactic sugar),但是相对于旧的原型链方式,其更加便捷,易熟悉和易理解,特别是针对刚学JavaScript的用户而言。

 

保存一个文档

你如果想创建和保存一个新的用户,那么你需要使用'.create()'和'.save()'方法,如下

***javascript
var connect = require('camo').connect;

connect('mongodb://localhost/camo_test').then(function(db) {

    var user = User.create({
        email: 'billy@example.com',
        password: 'sekret',
        name: 'Billy Bob',
        age: 28,
        previousLogins: [Date.now()]
    });

    return user.save();
}).then(function(u) {
    console.log('Saved user Billy!');
});

如上,你刚刚创建且保存了一个用户到MongoDB中

 

继承

现在要讲述Camo中最棒的部分啦。假设在你的webapp中,你有两个不同类型的用户类型——普通用户和高级用户。高级用户相对于普通用户有更多的特权和更多的类似支付信息等的数据。 为了避免只是为了增加额外的支付信息而重新书写'User' 模式(schema),我们可以使用继承:

***javascript
class ProUser extends User {
    constructor() {
        super();

        this.cardNumber = String;
        this.cardExp = String;
        this.cardSecurityCode = String;
        this.lastPayment = Date;
    }
}

你可以使用继承多次。继承将继承父类到子模式(schemas)中;如果父模式(schemas)或者其中的方法不满足你的设计,你可以覆盖它们。

 

内嵌数据

因为MongoDB数据不是写死的,这也是我们首先考虑使用它的原因。所以,当你想要增加一些比如地址的内置数据时,该怎么做?

你可使用‘EmbeddedDocument’来声明模式(shcema),并将其加入到已经存在的文档类(document class)中间。这些内置的文档不会被保存为单独的文档,可以被保存在其他的模式(schemas)中:

***javascript
var EmbeddedDocument = require('camo').EmbeddedDocument;

// User class here...

class Address extends EmbeddedDocument {
    constructor() {
        super();

        this.addressLine1 = String;
        this.addressLine2 = String;
        this.city = String;
        this.state = String;
        this.zip = String;
    }
}

class ProUser extends User {
    constructor() {
        super();

        // Credit card details here...

        this.billingAddress = Address;
        this.shippingAddress = Address;
    }
}

这然呢可以对待内置对象继续昂对待其他'Dpcument'对象一样,所以你可给其设置getters/setters,实例方法和静态方法。在所有的继承和内置模式(nested schemas)添加了之后,我们可以创建一个最终的如下乐死的文档

***json
{
    "email": "billy@example.com",
    "password": "a434287b3bfdd8de9f9f166f926dca10",
    "firstName": "Billy",
    "lastName": "Bob",
    "age": 28,
    "created": ISODate("2015-09-22T01:43:24.928Z"),
    "previousLogins": [ISODate("2015-11-16T03:53:46.678Z")],
    "cardNumber": "4242424242424242",
    "cardExp": "11/15",
    "cardSecurityCode": "123",
    "lastPayment": ISODate("2015-09-22T01:43:24.928Z"),
    "billingAddress": {
        "addressLine1": "123 Fake St.",
        "addressLine2": "",
        "city": "Cityville",
        "state": "NE",
        "zip": "12345"
    },
    "shippingAddress": {
        "addressLine1": "321 Code Circle",
        "addressLine2": "Suite 26",
        "city": "Villageville",
        "state": "NE",
        "zip": "54321"
    }
}

你获得了所有这些可以重新再shcemas中重新利用的代码,之后,你如果决定你的‘Address’内置数据需要包含‘Attn’这一行,你可以增加它,且其会包含到任何使用‘Address’ ‘EmbeddedDocument’的地方。

 

加载和删除文档

现在,你如果想要备份数据,那么可以使用类似针对MongoDb JavaScript驱动器的loadOne()和loadMany()方法。

***javascript
User.loadOne({email: 'billy@example.com'}).then(function(user) {
    console.log('Found user:', user.id);
});

删除文档,你可以在对象实例本身调用delete()方法,或者使用下面的静态方法:

‘deleteOne(query, options)’ 

`deleteMany(query, options)`

`loadOneAndDelete(query, options)`

 

结束语:

可以看更多的有关camo的内容(validation,hooks等等)

点击查看例子   

原文链接:https://blog.xervo.io/npm-install-camo

 

posted @ 2017-03-23 14:41  RachelChen  阅读(412)  评论(0编辑  收藏  举报