在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調用非同步介面了。