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. Node.js学习笔记(5)——关于child_process模块

    child_process是node一个比较重要的模块,通过它可以实现创建多线程,来利用多核CPU. 这个模块提供了四个创建子进程的函数. spawn.exec.execFile.fork. spaw ...

  2. centos7 安装rocketmq(quick start)

    Quick Start This quick start guide is a detailed instruction of setting up RocketMQ messaging system ...

  3. layui-概念-入门-总结

    layui教程:http://www.dosrun.com/layui/ 获得 Layui你可以在官网首页下载到 Layui 的最新版,也可以通过 GitHub得到Layui的开源包.目前只同步维护这 ...

  4. 电容有什么作用?为什么cpu电源引脚都并联一个电容?

    管理 随笔- 17  文章- 1  评论- 1  电容有什么作用?为什么cpu电源引脚都并联一个电容?   正文: 参考资料:http://blog.sina.com.cn/s/blog_7880d3 ...

  5. android中使用百度定位sdk实时的计算移动距离

    ;   //5秒刷新一次 private Handler refreshHandler = new Handler(){ //刷新界面的Handler public void handleMessag ...

  6. 智能手机的耗电特征及APP耗电量测试的两种方法

    文章陈述了手机发展趋势及耗电特性,集中讨论了时下最为关心的智能手机耗电问题,并介绍了测量手机软件耗电量的两种方法.此外还解释了为何运营商此前会提出收取微信的费用,心跳机制是什么. 美国著名手机公司Pa ...

  7. iOS自己定义对象保存到本地文件

    我是将聊天记录存到本地,里边用到了自己定义的对象.把数据转成Data格式存到本地.在转Data格式的时候报错了.这时候须要先将自己定义对象进行归档才干够转Data格式. 方法例如以下: 一.在.h文件 ...

  8. Tiny语言编译器简单介绍

    1.简单介绍:编译器是将一种语言翻译成还有一种语言的程序.编译器将源程序的代码作为输出,从而产生用目标语言编写的等价程序.比如源码为C/C++等高级语言,那么目标语言就是目标机器的机器代码.也就是能够 ...

  9. python 基础 5.2 类的继承

    一. 类的继承 继承,顾名思议就知道是它的意思,举个例子说明,你现在有一个现有的A类,现在需要写一个B类,但是B类是A类的特殊版,我们就可以使用继承,B类继承A类时,B类会自动获得A类的所有属性和方法 ...

  10. ifndef/define/endif 和 #ifdef 、#if 作用和用法

    为了能简单的看看某些linux内核源码,复习了一下c语音,今天汇总了一下关于宏定义的相关内容: 一.ifndef/define/endif用法: .h文件,如下: #ifndef XX_H #defi ...