何为Mongoose?简单的说,Mongoose就是对node环境中MongoDB数据库操作的封装,一个对象模型工具,将数据库中的数据转换为JavaScript对象以供我们在应用中使用。
官网:mongoosejs.com/window下安装MongoDB: www.runoob.com/mongodb/mon…Linux下安装MongoDB: http://www.runoob.com/mongodb/mongodb-linux-install.html
1、Schema、Model、Entity
在使用Mongoose前,先了解一下 Mongoose 中的三个概念:
Schema
、Model
、Entity(1) Schema
Schema是一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力。其实也可以看作是表结构的定义。
如何创建一个
Schema
?
const Articles = new Schema({
articleId: {type: String},
title: { type: String },
content: { type: String },
by: { type: String},
modifyOn: { type: Date, default: Date.now },
}, { collection: 'articles' });
(2) Model
由Schema发布生成的模型,具有抽象属性和行为的数据库操作对象。正是Model的存在,让我们操作数据库更加方便快捷。
依赖
Schema
生成一个Model
:
mongoose.model('articles', Articles);
(3) Entity
由Model创建的实体,它的操作也会影响数据库。
依赖
Model
,创造一个Entity
:
const article = new ArticlesModel(req.body); // 相当于调用了Model.create(req.body)
2、文章管理系统
理解了Schema、Model、Entity后,接下来我们来开始创建一个简单的文章管理系统。
技术栈:Mongoose:一个对象模型工具Express:基于Node.js 平台,快速、开放、极简的 web 开发框架。Pug:基于Node.js的模板引擎 Lodash:一个具有一致接口、模块化、高性能等特性的 JavaScript 工具库。
完整项目:Github:mongodb-pratice
启动项目:
cd mongoose-demo
npm install
npm start
项目结构说明:
- db:数据库相关操作文件,比如连接connect.js
- modules:模型,比如artilces,里面包含了路由、方法、模型等
- views:模板文件
- public:静态资源
- main.js:启动文件
3、项目详解
(1) 连接数据库
Mongoose连接数据库很简单:
// db/connect.js
const mongoose = require('mongoose');
exports.start = (success) => {
mongoose.connect('mongodb://localhost/blog', { useMongoClient: true });
const db = mongoose.connection;
db.on('error', console.error.bind(console, 'connection error:'));
db.once('open', () => {
// we're connected!
console.log('connected db: blog');
if (success) {
success();
}
});
};
上面的代码表示连接本地数据库blog
,同时绑定事件监听器来监听数据库是否连接成功。然后在启动文件中调用:
// main.js
const db = require('./db/connect');
db.start();
当然,你也可以将两个代码放在同一个文件。如果需要用户和密码,可以这样:
mongoose.connect('mongodb://root:password@localhost/blog')
当连接数据库成功后,我们就可以操作数据库了。(2) 创建模型
这里我们基于一个简单的文章系统来建模型:
// modules/articles/articles.model.js
const mongoose = require('mongoose'),
Schema = mongoose.Schema;
//先创建Schema
const Articles = new Schema({
articleId: {type: String},
title: { type: String },
content: { type: String },
by: { type: String},
modifyOn: { type: Date, default: Date.now },
}, { collection: 'articles' });
//通过Schema创建Model
mongoose.model('articles', Articles);
第一个参数就是结构对象,每一个键就是一个字段,你可以定义类型/默认值/验证/索引等;第二个参数是可选的(默认是取model的第一个参数加s),用来自定义Collection的名称。当然,你还可以这样定义名称:
mongoose.model('articles', Articles, 'articles');
注:我们不需手动去创建Collection,当你操作时,如Collection不存在,会自动创建。
(3) 配置API接口
在上面的代码中,我们连接了数据库,同时创建了可操作的Model,接下来我们就需要配置API接口供我们调用,这里就需要借助Express了:
// modules/articles/articles/route.js
const articleControllder = require('./articles.controller');
module.exports = (app) => {
app.route('/api/article/add')
.post(articleControllder.add);
app.route('/api/article/find')
.get(articleControllder.get);
app.route('/api/article/remove')
.delete(articleControllder.remove);
app.route('/api/article/update')
.put(articleControllder.update);
};
上面的代码中提供了增删改查四个api。(4) 基础操作(CRUD)
在上面路由中调用的方法:
// modules/articles/articles.controller.js
const mongoose = require('mongoose');
const ArticlesModel = mongoose.model('articles');
mongoose.Promise = global.Promise;
const commonFunction = require('../common/common_function');
const _ = require('lodash');
exports.get = (req, res) => {
const articleId = req.query['id'];
ArticlesModel.findById(articleId, (err, result) => {
if (err) {
return res.status(400).send({
message: '查找失败',
data: []
});
} else {
res.jsonp({
data: [result]
});
}
});
};
exports.add = (req, res) => {
req.body['articleId'] = commonFunction.getRandom();
req.body['modifyOn'] = new Date();
req.body['by'] = 'TG';
const article = new ArticlesModel(req.body);
article.save((err) => {
if (err) {
return res.status(400).send({
message: '新增失败',
data: []
});
} else {
res.jsonp({
data: [article]
});
}
});
};
exports.remove = (req, res) => {
const id = req.query['id'];
ArticlesModel.remove({'_id': id}, (err) => {
if (err) {
return res.status(400).send({
message: '删除失败',
data: []
});
} else {
res.jsonp({status: 1});
}
})
};
exports.update = (req, res) => {
const id = req.body['id'];
ArticlesModel.findById(id, (err, result) => {
if (err) {
return res.status(400).send({
message: '更新失败',
data: []
});
} else {
delete req.body['id'];
const articles = _.extend(result, req.body);
articles.save((err, result) => {
if (err) {
return res.status(400).send({
message: '更新失败',
data: []
});
} else {
res.jsonp({ data: [articles] });
}
})
}
})
};
这就是最基础的CRUD操作。
可能你会疑惑我没有导出Model,为什么这里可以用,其实我在引导文件中已经默认加载所有已发布的Model。
// main.js
...
const loadModels = () => {
files.forEach((v, k) => {
if (/model.js$/.test(v)) {
require(path.resolve(v));
}
});
};
loadModels();
...
通过获取modules文件夹里的所有文件,然后匹配后缀为model.js的模型文件,这样,你就可以在任何地方获取模型:
const ArticlesModel = mongoose.model('articles');
你还可以通过这篇文章了解MongoDB常用语句: 《MongoDB常用语句》
这里只是简单的讲解了Mongoose最基本的连接和CRUD,还有更多的内容需要我们去深入学习研究。
如有任何疑问或意见,欢迎在下方的评论区留言!