这两天跟着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(支持跨域),命令如下:
代码语言:javascript复制cnpm install express
cnpm install mongoose
cnpm install cors
使用Express启动http服务
Express 是一个保持最小规模的灵活的 Node.js Web 应用程序开发框架,为 Web 和移动应用程序提供一组强大的功能,简单易用,下面的代码演示了如何使用Express在指定的4001端口上监听,开启一个http服务,当然端口可以随意指定,只要和系统中其他不冲突即可,感觉使用起来比Java SpringBoot简单不少。
代码语言:javascript复制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
代码语言:javascript复制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)
新增产品
代码语言:javascript复制// 新增产品
app.post('/products', async function(req, res){
// 获取客户端请求的json数据
const data = req.body;
// 插入数据到产品表集合中
const product = await Product.create(data)
res.send(product)
})
查询所有产品记录
代码语言:javascript复制// 查询所有产品记录
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产品名称查询指定的产品信息
代码语言:javascript复制// 根据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请求修改产品信息
代码语言:javascript复制// 修改产品和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号删除某个产品
代码语言:javascript复制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测试文件如下:
代码语言:javascript复制@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
完整的示例代码
代码语言:javascript复制/* 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的顶部添加如下一行:
代码语言:javascript复制/* jshint esversion: 8 */
这样就可以正常使用async集合await调用异步接口了。