MEAN开发栈中使用MongoDB的时候,与之配对的ORM最好的选择就是Mongoose了。本文就和大家一起探讨一下如何使用Mongoose来实现MongoDB的增删改查。
为了能使文中的例子更加生动,我们会实现一个对于用户的增删改查的RESTful API。
Mongoose简介
mongoose是一个nodejs下,专门基于no-sql数据库mongodb的ORM框架。我们可以使用mongoose轻松实现对于mongodb的操作。要是用mongoose首先要在项目中添加这个框架:
$ npm install mongoose --save
注意,这里假设你已经安装了MongoDB。如果还没有,那么请参考这里下载,参考这里安装,并创建第一个数据库。
在项目中引用mongoose:
var mongoose = require('mongoose');
连接到已有数据库:
var url = 'mongodb://localhost/yourappdatabase';
mongoose.createConnection(url);
连接到数据库后就要处理里面的数据了。
定义一个Model
在处理增删改查以前,我们先看看mongoose的Model。这些Model就代表了MongoDB库里面的Document(MongoDB术语,相当于Sql数据库的表),以后的增删改查都要通过这个Model实现。
mongoose的Schema
是用来定义document的属性的。Schema
中也可以定义Methods
。
首先定义一个model:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
name: String,
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
admin: Boolean,
location: String,
meta: {
age: Number,
website: String
},
created_at: Date,
updated_at: Date
});
var User = mongoose.model('User', userSchema);
module.exports = User;
首先使用Schema
定义一个userSchema
,作为之后model里包含的字段和字段的类型使用。如果schema里包含了其他的对象,那么就把这个对象定义在meta属性内。
在mongoose的Schema里给字段指定类型时可用的类型有:
* String
* Number
* Date
* Buffer
* Boolean
* Mixed
* ObjectId
* Array
之后用mongoose.model
类创建Model。我们还可以在这里做更多,比如定义一个给用户密码加密的方法(稍后讲到)。
自定义方法
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var userSchema = new Schema({
name: String,
username: { type: String, required: true, unique: true },
password: { type: String, required: true },
admin: Boolean,
location: String,
meta: {
age: Number,
website: String
},
created_at: Date,
updated_at: Date
});
// 在Schema里添加自定义方法
userSchema.methods.capitalizeName = function () {
this.name = this.name.toUpperCase();
return this.name;
};
var User = mongoose.model('User', userSchema);
module.exports = User;
使用举例
下面就看看我们自定义的model和方法如何使用:
app.post('/new', function (req, res) {
var newGuy = new User({
name: req.body.name,
username: req.body.username,
password: req.body.password // 千万别用这种密码
});
newGuy.capitalizeName(function (err, name) {
if (err) {
res.send({error: err});
return;
}
console.log(`name is ${name}`);
});
newGuy.save(function (err) {
if (err) {
res.send({error: err});
} else {
res.send({message: 'done', user: newGuy});
}
这是在一个Http POST请求里获取用户的name
, username
, password
三个值。之后使用User
来创建一个新的用户newGuy
,调用方法newGuy.capitalizeName
,注意这个犯法里有回调。最后使用save
方法保存用户数据。由于在定义User
这个model的时候指定username
是唯一的,所以多次插入操作只会保存一条数据用户名相同的数据。
在保存以前调用的方法
我们在model里也定义了created_at
等关于时间的属性,这样就知道什么时候doc被创建。我们使用Schema
的pre
方法来保证保存以前可以调用执行一段特定的代码。
// 保存以前执行的代码
userSchema.pre('save', function (next) {
var currentDate = new Date();
this.updated_at = currentDate;
if (!this.created_at) {
this.created_at = currentDate;
}
next();
});
现在每次save都会执行这段代码,