在Express中对MongoDB数据库进行增删改查
- 2020 年 2 月 23 日
- 筆記
这两天跟着B站的Johnny老师学习NodeJs+Express+MongoDB相关的知识点,前后跟着做了1小时搞定NodeJs(Express)的用户注册、登录和授权、Element UI + NodeJs(Express)全栈开发后台管理界面、Express-9-MongoDB删除产品和DELETE请求等系列视频。本篇博客主要是学习在Express中如何对MongoDB数据库进行增删改查。
编码前的准备工作
首先要安装好NodeJs运行环境,配置好node和npm的环境变量,最好安装淘宝 NPM 镜像cnpm,安装配置好npm后,打开终端运行npm install -g cnpm –registry=https://registry.npm.taobao.org命令全局安装cnpm;然后在系统中安装好MongoDB,关于如何在Windows系统下安装MongoDB可以参考Windows 平台安装 MongoDB-菜鸟教程。我使用的系统是Windows10系统,采用的开发工具是Visual Studio Code,另外还需要在VSCode中安装REST Client插件,用于发送HTTP请求和查看服务端的响应信息,类似于PostMan,不过Rest-Client插件可以直接在VSCode中发送HTTP的GET、POST、PUT、DELETE请求,对于开发人员来说很方便,具体可以参考Johnny老师的B站视频VSCode中类似PostMan的API接口请求利器 – rest client,这篇视频快速的讲解了VSCode中Rest-Client的使用,具体的还可以看VSCode中Rest-Client的使用教程。 建立好上述开发环境后,打开VSCode,在一个目录中新建一个EXPRESS-TEST的文件夹,用于存放项目文件,新建一个server.js文件用于存放代码,test.http存放rest-client编写的接口用于测试客户端的http请求。 然后在VSCode中打开终端,使用cnpm命令安装express和MongoDB的数据库模块mongoose和cors(支持跨域),命令如下:
cnpm install express cnpm install mongoose cnpm install cors
使用Express启动http服务
Express 是一个保持最小规模的灵活的 Node.js Web 应用程序开发框架,为 Web 和移动应用程序提供一组强大的功能,简单易用,下面的代码演示了如何使用Express在指定的4001端口上监听,开启一个http服务,当然端口可以随意指定,只要和系统中其他不冲突即可,感觉使用起来比Java SpringBoot简单不少。
const express = require('express') const app = express() // 在4001端口上监听 app.listen(4001, () => { console.log('App is listening on port 4001!') })
在NodeJs中对MongoDB数据库进行增删改查
连接MongoDB数据库
新建一个MongoDB数据库模型,命名为express-test
const mongoose = require('mongoose') mongoose.connect('mongodb://localhost:27017/express-test', { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, }) // 创建产品Schema const Productschema = new mongoose.Schema({ title: { type: String, unique: true} }) // 定义MongoDB数据模型 (表=》集合) const Product = mongoose.model('Product',Productschema)
新增产品
// 新增产品 app.post('/products', async function(req, res){ // 获取客户端请求的json数据 const data = req.body; // 插入数据到产品表集合中 const product = await Product.create(data) res.send(product) })
查询所有产品记录
// 查询所有产品记录 app.get('/products', async function(req, res){ // const data = await Product.find().skip(1).limit(2) // const data = await Product.find().where({ // title: '华为' // }) const data = await Product.find().sort({ _id: -1 }) res.send(data) })
根据title产品名称查询指定的产品信息
// 根据title名称查询指定的产品信息 app.get('/products/:titleName', async function(req,res){ const titleName = req.params.titleName; Product.find({ "title": titleName }, function(err, doc){ if(err) { console.log(err) } else { res.json(doc) // res.send(res.json(doc)) } }) })
使用PUT请求修改产品信息
// 修改产品和PUT请求 // patch表示部分修改,put表示覆盖 //app.patch(); app.put('/products/:id', async function(req,res){ const product = await Product.findById(req.params.id); // 将客户端传过来的title赋值给产品(赋值不需要异步,因为它只是javascript中的一个内存操作,而查询、保存数据都需要和MongoDB连接需要异步) product.title = req.body.title; // 保存产品 await product.save(); res.send(product); })
根据客户端传递的id号删除某个产品
app.delete('/products/:id', async function(req, res){ // 根据客户端传递过来的id从MongoDB数据库中查询对应的产品 const product = await Product.findById(req.params.id); // 删除查询到的产品 await product.remove(); // 向客户端发送删除成功的信息 res.send({ success: true, }) })
使用Rest-Client编写http请求
VScode中的Rest-Client有一个规定,就是http请求文件必须以http为后缀,比如说tets.http文件。 本EXPREES-TEST项目中对应的test.http测试文件如下:
@url=http://localhost:4001 @json=Content-Type: application/json ### products page GET {{url}}/products ### post 新增产品 POST {{url}}/products Content-Type: application/json { "title": "我的手机" } ### put 修改产品 PUT {{url}}/products/5e48c999e12a60686cbad30b Content-Type: application/json { "title": "Apple" } ### 删除某个产品 DELETE {{url}}/products/5e4aaa812d6048635c877fd1 ### 静态文件托管 get {{url}}/index.html
完整的示例代码
/* jshint esversion: 8 */ // expess模块 const express = require('express') const app = express() app.use(express.json()) // MongoDB模块 const mongoose = require('mongoose') mongoose.connect('mongodb://localhost:27017/express-test', { useNewUrlParser: true, useUnifiedTopology: true, useCreateIndex: true, }) // 创建产品Schema const Productschema = new mongoose.Schema({ title: { type: String, unique: true} }) // 定义MongoDB数据模型 (表=》集合) const Product = mongoose.model('Product',Productschema) // 往MongoDB数据库中插入数据 // Product.insertMany([ // {title: 'Apple'}, // {title: '华为'}, // {title: '三星'}, // {title: '小米'}, // {title: 'Oppo'}, // {title: 'Vivo'}, // ]) // 删除所有数据 // Product.deleteMany({}, function(err, doc) { // if(err) { // console.log(err) // } else { // console.log(doc) // } // }); // 允许跨域 app.use(require('cors')()) // 路由:express 静态文件托管 // app.use('/static', express.static('public')) app.use('/', express.static('public')) // 新增产品 app.post('/products', async function(req, res){ // 获取客户端请求的json数据 const data = req.body; // 插入数据到产品表集合中 const product = await Product.create(data) res.send(product) }) // 查询所有产品记录 app.get('/products', async function(req, res){ // const data = await Product.find().skip(1).limit(2) // const data = await Product.find().where({ // title: '华为' // }) const data = await Product.find().sort({ _id: -1 }) res.send(data) }) // 查询单个产品记录 产品详情页的接口 // app.get('/products/:id', async (req,res) => { // const data = await Product.findById(req.params.id) // res.send(data) // }) // 根据title名称查询指定的产品信息 app.get('/products/:titleName', async function(req,res){ const titleName = req.params.titleName; Product.find({ "title": titleName }, function(err, doc){ if(err) { console.log(err) } else { res.json(doc) // res.send(res.json(doc)) } }) }) // 修改产品和PUT请求 // patch表示部分修改,put表示覆盖 //app.patch(); app.put('/products/:id', async function(req,res){ const product = await Product.findById(req.params.id); // 将客户端传过来的title赋值给产品(赋值不需要异步,因为它只是javascript中的一个内存操作,而查询、保存数据都需要和MongoDB连接需要异步) product.title = req.body.title; // 保存产品 await product.save(); res.send(product); }) // 修改产品信息 app.get('/products/update/:titleName', async function(req,res){ const titleName = req.params.titleName; Product.update({ title : titleName }, {"$set":{title: "My Oppo A5"}}, function(err, doc){ if(err) { console.log(err) } else { res.json(doc) // res.send(res.json(doc)) } }) }) // 根据客户端传递的id号删除某个产品 app.delete('/products/:id', async function(req, res){ // 根据客户端传递过来的id从MongoDB数据库中查询对应的产品 const product = await Product.findById(req.params.id); // 删除查询到的产品 await product.remove(); // 向客户端发送删除成功的信息 res.send({ success: true, }) }) // 在4001端口上监听 app.listen(4001, () => { console.log('App is listening on port 4001!') })
我在实际使用VSCode的过程中,当使用async集合await调用MongoDB实现异步调用时保存,需要在源代码文件server.js的顶部添加如下一行:
/* jshint esversion: 8 */
这样就可以正常使用async集合await调用异步接口了。