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 >= ;
} static getVoters() {
return User.loadMany({ age: { $gte: } });
}
}

虽然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: ,
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": ,
"created": ISODate("2015-09-22T01:43:24.928Z"),
"previousLogins": [ISODate("2015-11-16T03:53:46.678Z")],
"cardNumber": "",
"cardExp": "11/15",
"cardSecurityCode": "",
"lastPayment": ISODate("2015-09-22T01:43:24.928Z"),
"billingAddress": {
"addressLine1": "123 Fake St.",
"addressLine2": "",
"city": "Cityville",
"state": "NE",
"zip": ""
},
"shippingAddress": {
"addressLine1": "321 Code Circle",
"addressLine2": "Suite 26",
"city": "Villageville",
"state": "NE",
"zip": ""
}
}

你获得了所有这些可以重新再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

npm-install camo的更多相关文章

  1. 转:解决npm install慢的问题

    使用NPM(Node.js包管理工具)安装依赖时速度特别慢,为了安装Express,执行命令后两个多小时都没安装成功,最后只能取消安装,笔者20M带宽,应该不是我网络的原因,后来在网上找了好久才找到一 ...

  2. Npm install failed with “cannot run in wd”

    Linux环境下,root账户,安装某些npm包的时候报下面的错误,例如安装grunt-contrib-imagemin时: Error: EACCES, mkdir '/usr/local/lib/ ...

  3. npm全局安装和本地安装和本地开发安装(npm install --g/--save/--save-dev)

    详细说明参考:http://www.cnblogs.com/PeunZhang/p/5629329.html 我个人理解: 1.全局安装(npm install -g)是为了用命令行,比如在windo ...

  4. npm install报错Error: ENOENT

    E:\projects\ueditor\ueditor1_4_3_3-src>npm installError: ENOENT, stat 'C:\Users\Lucas\AppData\Roa ...

  5. Windows环境下npm install常见错误

    Windows环境下npm install安装包依赖时,常出现一些错误,下面为个人解决办法: 错误一 缺少python环境: G:\nodejs\moviesite\node_modules\bcry ...

  6. npm install socket.io遇到的问题

    解决方法: 输入 npm install socket.io 前,先执行下面 npm config set proxy "http://yourip:port" 生产的npm-de ...

  7. centos7中 npm install express 时Error: Cannot find module 'express'错误

    费了很大劲最后在网上找到,在自己的工程目录下再次执行npm install express搞定.

  8. npm install -g 全局安装总是出现permission权限问题的解决方案

    npm install -g 全局安装总是出现permission权限问题的解决方案 开始使用node的时候,在使用npm安装global packages时,习惯性地使用npm install -g ...

  9. NPM install - killed error solution

    在接手一个Node项目的时候,npm install.却出现了"killed"的错误.以为是Node版本的问题,熟练地切换了0.11与0.10版,同样无解. 由于新的npm版本吧, ...

  10. npm install时报错 npm ERR!Windows_NT 6.1.7601

    解决办法:先设置代理为空 npm config set proxy null, 然后再npm install cnpm -g --registry=https://registry.npm.taoba ...

随机推荐

  1. java个人感想

    java与c++相比,摒弃了c++的指针,把c++中的stl封装成一个库,而且改变了当中的某些方法,使用方法也产生了非常多不同,读者在编程过程中须要自己细细体会 个人觉得三大框架基于前端+领域逻辑+数 ...

  2. robotframe使用之时间控件

    robotframe使用之时间控件 正常的页面,时间控件会写在一个iframe里面,所以robotframework找不到对的ID或者xpath等. 要解决这个问题必选先显示iframe. 使用关键字 ...

  3. H5缓存机制学习记录

    参考文章:http://mp.weixin.qq.com/s?__biz=MTEwNTM0ODI0MQ==&mid=404724239&idx=1&sn=e0a2887f9ff ...

  4. linux下安装redis报错问题。

    1.使用tar -xzvf redis-2.4.5.tar.gz来解压安装包 2.使用make命令来编译Redis 如果出现错误需要查看是否缺少gcc gcc-c++ zmalloc.h:50:31: ...

  5. 【puppeteer+Node.js安装环境】之WebStorm编辑器运行失败问题:Error: Cannot find module 'puppeteer'并且代码出不来“asnyc”标识以及有红色波浪线解决办法

    现象一: module.js:557     throw err;     ^ Error: Cannot find module 'puppeteer'  at Function.Module._r ...

  6. 理解cas

    前言 CAS(Compare and Swap),即比较并替换,实现并发算法时常用到的一种技术,Doug lea大神在java同步器中大量使用了CAS技术,鬼斧神工的实现了多线程执行的安全性. CAS ...

  7. Intellj IDEA光标替insert状态,back键无法删除内容

    Intellj IDEA光标为insert状态,无法删除内容导入项目后,发现打开java文件的光标是win系统下按了insert键后的那种宽的光标,并且还无法删除内容,且按删除(delete)键也只见 ...

  8. PowerBuilder -- 数字金额大写

    //==================================================================== // 事件: .pub_fc_change_number( ...

  9. 奇妙的go语言(開始篇)

    [ 声明:版权全部.欢迎转载,请勿用于商业用途.  联系信箱:feixiaoxing @163.com] 从前接触脚本语言不多,可是自从遇到go之后,就開始慢慢喜欢上了这个脚本语言.go语言是goog ...

  10. c# 备份数据

    #region 备份数据文件 /// <summary> /// 备份数据文件 /// </summary> /// <param name="strFileN ...