Mongoose 以及 基本 CRUD
Mongoose 以及 基本 CRUD
Mongoose 介绍
Mongoose 是 MongoDB 的一个抽象层,有点像是 Express 对 Node 的感觉。
官方文档的两个介绍大概说明了 Mongoose 是干嘛的:
Mongoose is a MongoDB object modeling tool designed to work in an asynchronous environment. Mongoose supports both promises and callbacks.
Let’s face it, writing MongoDB validation, casting and business logic boilerplate is a drag. That’s why we wrote Mongoose.
首先,Mongoose 是一个在异步环境下使用的 MongoDB 对象模型工具,其次,Mongoose 可以减少 MongoDB 验证、类型转换,以及业务逻辑样板的代码量。
关于 MongoDB 的部分,可以看这个——MongoDB 的安装和基础 CRUD,这里要用的也不会超过之前对 MongoDB 的了解了。
安装 Mongoose
Mongoose 在 npm 上有依赖,可以直接用 npm 安装:
npm i mongoose
等下载好了就可以直接在项目里面使用 Mongoose 了。
连接数据库
配置
config.env
config.env
中的配置如下:# 远程的MongoDB路径,我用的是 Atlas 的免费版进行学习,这点在上面的 MongoDB 文章里提到,感兴趣的可以去看看 DATABASE=mongodb+srv://<USERNAME>:<PASSWORD>@<CLUSTER_ENV>/<DOCUMENTS>?retryWrites=true&w=majority # 上面用 <> 包起来的变量都会被代替掉,不会放出来的 DB_USERNAME=some-random-username DB_PASSWORD=some-random-password CLUSTER_ENV=atlas-cluster-env DOCUMENTS=atlas-documents# 也可以使用本地的 Mongodb 进行学习 # 这里的 <DOCUMENTS> 用自己想用的就行了,如果没有的话,MongoDB 会自己创立的 DATABASE_LOCAL=mongodb://localhost:27017/<DOCUMENTS>
连接数据库
目前在
server.js
文件中进行连接// 导入必要的包 const mongoose = require("mongoose"); const dotenv = require("dotenv");// dotenv 必须先读取环境配置,等 app 声明调用了再找配置就来不及了 dotenv.config("./config.env");// 必要的环境配置 const app = require("./app"); // replace 必要的 connection string // 包括 用户名、密码、cluster、document,确保和云端信息一致 const DB = process.env.DATABASE.replace("<USERNAME>",process.env.DB_USERNAME );// 连接 MongoDB // 云端的连接方法 mongoose.connect(DB, {// 一些优化和减少 warning 的配置useNewUrlParser: true,useCreateIndex: true,useFindAndModify: false,useUnifiedTopology: true,}).then(() => {console.log("DB successfully connected");}); // 本地的连接方法基本差不多,只是需要把 DB 换成 process.env.DATABASE_LOCAL 就好了 /* mongoose.connect(process.env.DATABASE_LOCAL, {// 一些优化和减少 warning 的配置useNewUrlParser: true,useCreateIndex: true,useFindAndModify: false,useUnifiedTopology: true,}).then(() => {console.log("DB successfully connected");});*/
这个时候在本地运行的 express 服务器就可以连接上远程的数据库了。
创建 Model
这是 Model 层的业务,先创建一个 schema,然后再以 model 的形式导出,让 controllers 使用。
const mongoose = require("mongoose");// 为了方便,暂时还不会自创 Schema,里面的 type 都是 JS 自己的
const productSchema = new mongoose.Schema({product: {type: String,// 第二个参数会决定 报错信息required: [true, "This will be a warning message"],// 目前假设每个产品都有独一无二的名字unique: true,trim: true,},createdAt: {// MongoDB 会依照 传过去的毫秒 自动创建当前时间type: Date,default: Date.now(),},price: {type: Number,required: [true, "A product must have price"],},
});const Product = mongoose.model("Product", productSchema);module.exports = Product;
实现 Controller
即实际的业务逻辑,这里假设 routers
里面已经通过 request
调用了 controller
里面的函数。最外层的文件如下:
// 即上文 export 的 Product
const Product = require('../models/productModel');// 等待实现的 CRUD
exports getAllProducts = async (req, res) => {}exports getProduct = async (req, res) => {}exports createProduct = async (req, res) => {}exports deleteProduct = async (req, res) => {}exports updateProduct = async (req, res) => {}
Create
即 createProduct
方法。
exports.createProduct = async (req, res) => {// 从 req.body 里面已经穿来了一个 JSON对象// 现在暂时是在 postman 里面写死的,之后会写 View 或者用 React 再做一个 VMtry {const product = await Product.create(req.body);res.status(201).json({status: "Success",data: {product,},});} catch (err) {res.status(400).json({status: "fail",message: err,});}
};
Read
即两个方法:find()
和 findById()
。
exports.getAllProducts = async (req, res) => {try {const products = await Product.find();res.status(200).json({status: "Success",results: products.length,data: {products,},});} catch (err) {res.status(404).json({status: "fail",message: err,});}
};exports.getProduct = async (req, res) => {try {const product = await Product.findById(req.params.id);res.status(200).json({status: "Success",data: {product,},});} catch (err) {res.status(404).json({status: "fail",message: err,});}
};
Update
还没有实现 updateMany()
,先实现 findByIdAndUpdate()
,这个部分的代码是被 patch()
所调用的。
exports.updateProduct = async (req, res) => {try {const product = await Product.findByIdAndUpdate(req.params.id, req.body, {// new 是为了返回更新后的 数据,默认返回是未被更新的数据new: true,runValidators: true,});res.status(200).json({status: "Success",data: {product,},});} catch (err) {res.status(404).json({status: "fail",message: err,});}
};
Delete
即 findByIdAndDelete()
函数。
exports.deleteProduct = async (req, res) => {try {await findByIdAndDelete(req.params.id);} catch (err) {res.status(204).json({status: "Success",});res.status(404).json({status: "fail",message: err,});}
};
到这里基础的 CRUD 就全都完成了。
试了之后才发现,真的非常简单。
下一步做的优化就是 findById()
里面传 query param,一些过滤的优化,然后再考虑把 CRUD 的 try{} catch (err) {}
封装一下。
目前的 try/catch
其实也非常简陋,很多判断都没有做。
学习项目的配置
简单地说一下吧,之前好像在那个学习笔记里面有放过……不过现在结构这么简单,有时间找都重新写完了。
之后还是应该抽空把 node 和 express 部分的笔记单独抽离出来。
结构
一个典型的 MVC 结构,如下:
|- src
| |- controllers
| | |- productController.js
| |- models
| | |- productModel.js
| |- routes
| |- app.js
| |- config.env
| |- package.json
| |- server.js
目前 View 还没有开始折腾,现在折腾 API 部分,这也就是为什么开始学 MongoDB 和用 Mongoose 了。
mondels
里面放的就是 MVC 里的 M,即 Model。这里面主要是一些 Schema Definition,定义数据类型、是否是必须的,等一些细节方面的东西。在 Schema 里面定义好了之后,如果在进行 CRUD 的操作时,数据不对的话,就会报错。所以说在 Mongoose 的介绍里面也说了,写 MongoDB 的验证很烦,主创开发 Mongoose 的原因之一就是为了操作 MongoDB 的时候没这么麻烦。
controllers
处理的是业务逻辑,即传统的 CRUD 操作。
routes
处理的是路由,在 RESTful API 里面,资源的路径名字始终保持一致,根据传来的 HTTP request 去进行 CRUD 的操作。这时候就需要路由去判断传来的 HTTP request,随机调用对应的 controller 里对应的方法。
具体可以查看 IBM 的文档,在 参考 里。
app.js
app 相关的配置,目前负责调用配置一些简单的中间件,以及对
routers
的管理。config.env
一些配置,包括 MongoDB 网址、用户名、密码之类的会放在这里方便管理。
package.json
server.js
服务器相关的,目前连接 MongoDB 的操作会放在这里。
package.json
在这篇教学里面,除了 Mongoose 之外,还会用到 dotenv
去进行环境配置。
"dependencies": {"dotenv": "^8.2.0","mongoose": "^5.12.3"
}
参考
-IBM - REST APIs
Mongoose 以及 基本 CRUD相关推荐
- 给mongoose find()/findOne()查询的结果添加额外的属性
在学习 mongoose 的时候,碰到一个需要注意的地方. 给查询结果添加额外的属性时,不能直接在这个结果对象上添加属性.原因和解决方案往下看. 假设 User 集合有一个 name 字段: cons ...
- Node+express+mongoose前端实现简单crud接口
Node+express+mongoose前端实现建单crud接口 准备工作:需要安装依赖如下:node,express,mongoose,cors,requier-all 入口文件:index.js ...
- Mongoose的CRUD方法
mongoose 的CRUD -C creat: 模型对象.create(文档对象,回调函数) 模型对象.create(文档对象) -R Read: 模型对象.find(查询条件,[投影]) 注意⚠️ ...
- [转] mongoose学习笔记(超详细)
名词解释 Schema: 一种以文件形式存储的数据库模型骨架,不具备数据库的操作能力 Model: 由Schema编译而成的假想(fancy)构造器,具有抽象属性和行为.Model的每一个实例(ins ...
- Nodejs+Express学习二(Mongoose基础了解)
学习Node注定少不了与数据库打交道,而MongoDB和Node可以说是绝配,这篇主要是简单介绍Mongoose这个模块. 由于本人也是边学边写的这篇文章,绝对会有新手的味道,请大神看到这里就表往下看 ...
- 前端笔记之NodeJS(四)MongoDB数据库Mongoose自制接口MVC架构思想|实战
一.MongoDB数据库 1.1 NoSQL简介 随着互联网web2.0网站的兴起,传统的SQL数据库(关系数据库)在应付web2.0网站,特别是超大规模和高并发的SNS(social network ...
- 手把手教你用nestjs框架7分钟生成crud风格接口
Tobenew ,感谢! node.js mongodbnestjs 1.安装nest.js框架 nest.js官方开发文档 全局安装nest框架 npm i -g @nestjs/cli 2. 新 ...
- nodejs mongoose建模实践
2019独角兽企业重金招聘Python工程师标准>>> 一直以来mongoose学习都是比较麻烦的,mongoose-cli试图简化学习和测试mongoose部分,并通过app开发流 ...
- mongoose mysql_mongoose入门
mongoose入门 MongoDB是一个开源的NoSQL数据库,相比MySQL那样的关系型数据库,它更显得轻巧.灵活,非常适合在数据规模很大.事务性不强的场合下使用.同时它也是一个对象数据库,没有表 ...
最新文章
- Linux下安装 boost 库
- C语言程序设计 细节总结(第9章 结构体共用体枚举)
- 统计数字,空白符,制表符_为什么您应该在HTML中使用制表符空间而不是多个非空白空间(nbsp)...
- 每日一皮:从项目的开始到结束,开发人员的变化...
- [发布]Lucene索引分析工具Luke.Net 0.5升级版 (兼容Lucene.Net 2.9.4.1)
- spring源码分析之spring-jms模块详解
- HP DL388G5 安装64位linux虚拟系统出错!
- android 8种对话框(Dialog)使用方法汇总
- 40访问者模式(Visitor Pattern)
- LintCode 1671. 玩游戏(贪心、难)
- 【2019杭电多校第六场1008=HDU6641】TDL(思维)
- 一文带你快速全面掌握Java反射机制面试题
- Meterpreter命令详解
- 5G NR — 基站(Base Station)
- python基础螺旋线
- 信息安全从业者书单推荐
- IROS2020 论文阅读
- 为什么OSPF在广播网络里面,DD和LSR采用单播,而LSU hello采用组播。
- 2023-2029全球斑马鱼行业调研及趋势分析报告
- pc_lint的用法转
热门文章
- 程序员日常:男程序员手腕上一般戴什么?程序员的第一只手表
- 海外主体企业微信公众号如何开通及认证?
- i.MX 6ULL 驱动开发 十四:LED(paltform驱动框架)
- 【Skywalking】集成Sl4fj2报错:NoClassDefFoundError,com/lmax/disruptor/TimeoutBlockingWaitStrategy
- vue中将 后台返回的0,1等 代码转换成 男,女等汉字。
- Android仿酷狗动感歌词(支持翻译和音译歌词)显示效果
- C语言应该怎么玩——函数
- poi操作ppt生成图表
- MongoDB 自学笔记(入门级教程)
- Code First 2