在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调用异步接口了。