mongoose
mongoose 是 node 中提供操作 MongoDB 的模块
能够通过 node 语法实现 MongoDB 数据库的增删改查
下载方式
npm i mongoose
yarn add mongoose (推荐)
语法:
// 一, 导入模块 const mongoose = require('mongoose') // 二, 连接数据库 const db = mongoose.createConnection('mongodb://user:pass@localhost:port/database', { useNewUrlParser: true, useUnifiedTopology: true}, err=>{ if(err){ console.log('------------------') console.log('数据库连接失败') console.log('-------------------'); return } console.log('数据库连接成功'); }) // 三, 设置数据模型 (声明是哪个集合, 限制字段个数和字段类型) const model = db.model('user',{ name:{type:String, defalut:'username'}, age: {tyoe: Number}, sex: {type: String} }) // 四, 创建实例操作 //增--------------------------------------------- const insertObj = new model(数据对象) // 方法1: insertObj.save((err) => db.close()) // 方法二: insertObj.save() .then(res=>{ return res }) .catch(err => { console.log('插入失效' + err) return false }) // 删------------------------------------------ // 方法一: model.remove/deleteOne/deleteMany(条件对象, (err) => db.close()) // 方法二: model.deleteOne(条件对象) .then(res => { return res.deletedCount }) .catch(err => { console.log('删除失败' + err) return false }) // 改--------------------------------------------- // 方法一: model.update/updateOne/updateMany(条件对象, 数据对象, (err) => db.close()) // 方法二 model.updateOne(条件对象, 数据对象) .then(res => { return res.nModified }) .catch(err => { console.log('修改失败' + err) return false }) // 查-------------------------------------------------- // 方法一: model.find/findOne(条件对象, 要显示的字段数据对象, (err, result) => db.close()) // 方法二: model.findOne(条件对象) .then(res => { return res }) .catch(err => { console.log('查找失败' + err) return false })
数据库连接状态
- connect() 返回的是一个待定状态, 在 mongoose中有一个属性叫 connection 用来表示数据库的连接
- 通过监视改对象可以用来监听数据库的连接与断开
- 数据库连接成功事件
mongoose.connection.once(‘open’, () => {})
- 数据库断开事件
mongoose.connection.once(‘close’, () => {})
schema
数据库中的schema为数据库对象的集合,是mongoose里会用到的一种数据模式,可以理解为表结构的定义,每个 schema 都会映射到一个 MongoDB collection ,并定义这个collection里的文档的构成.
var stuSchema = new Schema({})
Mongoose 的一切始于 Schema
作用: 用来约束 MongoDB文档数据
model
Models 是从 Schema
编译来的构造函数。
var stuModel = mongoose.model('student', stuSchema)
要映射的集合名, 创建的约束(Schema对象)
后面我们通过模型来管理集合中的数据
接口概念
就是一个文件(js\json\php)等, 主要响应JSON数据( 操作方便,体积小 ) 或 XML数据
{ status: 1/0, msg: '提示信息' } ------------------ <xml> <status>1.0</status> <msg>提示信息</msg> </xml>
只要响应json数据所有语言都可以操作, 例如ios/Android等
推荐
{ meta: { msg: 提示信息, status: 状态码 (200/201/301/302/400/401/403/404/500) }, data: 数据 }
接口开发规范 Restful API
- 项目所有模块有统一的标准
- 看URL就知道要操作的资源是什么
- 看Http Method 就知道操作动作是什么, 是添加(post) 还是删除(delete)
- 看Http Status Code 就知道操作结果如何, 是成功(200) 还是内部错误
常用的http状态码及使用场景:
状态码 | 使用场景 |
400 | bad request 常用在参数校验 |
401 | unauthorized 未经验证的用户,常见于未登录。如果经过验证后依然没权限,应该 403(即 authentication 和 authorization 的区别) |
403 | forbidden 资源不存在 无权限 |
404 | not found |
500 | internal server error 非业务类异常 |
503 | service unavaliable 由容器抛出,自己的代码不要抛这个异常 |
接口文档开发
apiDoc是node.js中的一个模块,通过这个模块可以快速生成接口文档.
前提写接口的时候把注释加上
用法
- 下载模块, 后期根据命令基于注释生成文档(仅一次)
npm install apidoc -g
- 在项目根目录创建 apidoc.json文件(仅一次)
{ "name": "example", "version": "0.1.0", "description": "apiDoc basic example", "title": "Custom browser title", "url": "https://api.github.com/v1" }
- 写接口注释
/** * @api {get} /stu 学生模块列表 * @apiName Add * @apiGroup stu * * @apiParam {Number} pageno 当前页 *@apiParam {Number} pagesize 每页显示条数 * @apiSuccess {String} meta 状态码&提示信息 * @apiSuccess {String} data 数据 **/
- 生成接口文档
apidoc -i ./接口注释目录 -o ./接口文档存放目录
预定义模式修饰符
let MenuSchema = mongoose.Schema({ name:{ type:String, trim: true //定义mongoose模式修饰符 去掉空格 }, age:Number, status: Number, });
自定义修饰符
set()
let MenuSchema = mongoose.Schema({ name:String, age:Number, status: Number, pic: { type:String, set(url){ //增加数据的时候对pic字段进行处理 //url 可以获取pic的值, 返回的数据就是pic在数据库实际保存的值 if(!url) { return '' } else { if(url.indexOf('http://') != 0 && url.indexOf('https://') != 0) { return 'http://' + url } return url } } } });
get() 一般无用
let MenuSchema = mongoose.Schema({ name:{ type:String, trim: true, //定义mongoose模式修饰符 去掉空格 get(params) { return "200" + params } }, age:Number, status: Number, });
set会存在数据库,get不会
索引
优化查询的速度
let MenuSchema = mongoose.Schema({ sn: { type:Number, // 唯一索引 unique: true }, name: { type: String, // 普通索引 index: true } })
静态方法
//通过find方法获取 sn的数据, this关键字获取当前的model MenuSchema.statics.findBySn=function (sn, cb) { this.find({"name":sn}, function (err, docs) { cb(err,docs) }) }
数据校验
required: //数据必须传入 max: //用于Number 类型数据, 最大值 min: //用于Number 类型数据, 最小值 enum: //枚举类型,要求数据必须满足枚举值 ['0','1','3'] match: //增加的数据必须符号match (正则)的规则 用在string类型 maxlength: //最大长度 minlength: //最小长度
validate
自定义校验
validate: function(sn) { return sn.length >= 10 }
聚合管道
两个表的关联
menumodel.aggregate([ { $lookup: { from: "order_item", //要关联的表 localField: "data", // 主表要关联的字段 foreignField: "data", //副表要关联的字段 as:"items" //关联后的数据存放的地方 } }, { $match: {id: mongoose.Types.ObjectId('')} //通过objectid查找数据 } ], (err, docs) => { if(err) { console.log(err) return; } console.log(JSON.stringify(docs)); })
多个表的关联