记一次nodejs+mongodb数据库项目学习经历

2,800 阅读5分钟

前记

在学习vue的路上从开始看api到写了几个小项目后,对vue有了一定的了解,但是一直没做过web全栈类的项目。这次跟着慕课的视频做了web全栈类项目,特此一记,来巩固下知识!

github地址:github.com/Conankids/m…

项目地址:shop.jiaomingchao.com

技术

前端

使用vue-cli搭建前端基本框架+vue-router完成前端路由+vuex管理状态

后端

基于nodejs使用express脚手架生成express项目框架+mongoose操作数据库

数据库

mongodb数据库

项目搭建

  1. 安装vue-cli
  2. 初始化vue项目目录
sudo vue init webpack 项目名称    (由于我是mac电脑,需要sudo权限;项目名必须是小写,大写字母会报错)
  1. 写vue项目
  2. 在未建立后端代码的时候可以使用webpack自带的插件进行mock数据,在build/webpack.dev.conf.js里面做如下修改,在接口请求到/goods的时候就会请求到我们事先写好的json数据了
//mock数据
const goodsData = require('./../mock/GoodsList.json')
devServer: {
   ...
     before:function (app) {
      //模拟mock数据
         app.get('/goods',function (req,res) {
             res.json(goodsData)
         })
     }
  },
  1. 安装express脚手架
sudo npm i -g express-generator   
  1. 初始化express项目目录
进入到项目目录下  express server  
  1. 安装mongodb数据库

技术点详解

前端

  1. 使用vue-router实现前端路由功能
  2. 使用vue-infinite-scroll插件实现上拉加载功能
  3. 使用axios来实现前后端通讯
  4. 使用vue-lazyLoad插件实现图片的懒加载
  5. 使用尤大的currency.js实现全局过滤器功能
  6. 使用vuex管理购物车数量

(所用前端技术比较常见,不是本次记述重点)

后端

  1. 安装mongoose插件

mongoose基础入门

npm i mongoose -S

2.创建models文件目录用来存放数据库字段模型(users、goods)

const mongoose = require('mongoose') //引入mongoose

const schema = mongoose.Schema  

//new一个schema对象,参数为字段及其类型
const userSchema = new schema({
    "userId": String,
    "userName": String,
    "userPwd": String,
    "orderList": Array,
    "cartList": [{
        "productId": String,
        "productName": String,
        "salePrice": String,
        "productImage": String,
        "checked": String,
        "productNum": String
    }],
    "addressList": [{
        "addressId": String,
        "userName": String,
        "streetName": String,
        "postCode": Number,
        "tel": Number,
        "isDefault": Boolean
    }]
})

//模型创建之后暴露出来,mongoose.model('模型名称',模型对象,数据库集合名(默认会添加s可以不填,否则需要制定数据库创建出来的模型名))
module.exports = mongoose.model('user', userSchema)

3.创建路由文件

在routes文件夹下创建users.js和goods.js分别对应/users和/goods路由。同时需要在app.js中进行引用。

var indexRouter = require('./routes/index');//index路由
var usersRouter = require('./routes/users');//users路由
var goodsRouter = require('./routes/goods');//goods路由

app.use('/', indexRouter);
app.use('/users', usersRouter);
app.use('/goods', goodsRouter);

4.连接数据库

//引入依赖
const express = require('express')
const mongoose = require('mongoose')
const goods = require('../models/goods')
const users = require('../models/users')

const router = express.Router()
//连接数据库
//connect()最简单的使用方式,就是只要传入url参数即可,如下所示。连接到本地localhost的db1服务器
//mongoose.connect('mongodb://localhost/db1');
//如果还需要传递用户名、密码,则可以使用如下方式
//mongoose.connect('mongodb://username:password@host:port/database?options...');

mongoose.connect('mongodb://140.143.234.88:27017/db_demo')

//监听连接状态(已连接)
mongoose.connection.on('connected', () => {
    console.log('MongoDb connected successful!')
})
//失败
mongoose.connection.on('err', () => {
    console.log('MongoDb connected fail!')
})
//断开连接
mongoose.connection.on('disconnected', () => {
    console.log('MongoDb disconnected!')
})

5.编写获取产品列表接口(mongoose查询用法)

router.get('/list', (req, res, next) => {
    const page = parseInt(req.param('page')) //获取页码参数
    const pageSize = parseInt(req.param('pageSize')) //获取一页有多少条数据参数
    const sort = req.param('sort') //获取排序参数
    const priceLevel = req.param('priceLevel') //获取价格区间
    const skip = (page - 1) * pageSize //计算跳过多少条
    let params = {} //查询参数
    let startPrice = '', endPrice = ''

    if (priceLevel != 'all') {
        switch (priceLevel) {
            case '0':
                startPrice = 0
                endPrice = 100
                break
            case '1':
                startPrice = 100
                endPrice = 500
                break
            case '2':
                startPrice = 500
                endPrice = 1000
                break
            case '3':
                startPrice = 1000
                endPrice = 5000
                break
        }
        params = {
            salePrice: {
                $gt: startPrice,
                $lt: endPrice
            }
        }
    }

    const goodsModel = goods.find(params).skip(skip).limit(pageSize) //查询后跳过多少条限制一页多少条,返回计算后的模型
    goodsModel.sort({'salePrice': sort}) //对模型进行排序
    goodsModel.exec((err, doc) => {
        if (err) {
            res.json({
                status: -1,
                msg: err.message
            })
        } else {
            res.json({
                status: 0,
                msg: '',
                result: {
                    count: doc.length,
                    list: doc
                }
            })
        }
    })
})

6.编写加入购物车接口(mongosse增加数据用法)

router.post('/addCart', (req, res, next) => {
    const userId = req.cookies.userId
    const productId = req.body.productId
    let userProductId = ''

    //查询user表
    users.findOne({userId: userId}, (err1, userDoc) => {
        if (err1) {
            res.json({
                status: -1,
                msg: err.message
            })
        } else {
            if (userDoc) {
                //遍历user表的购物车列表是否已有此商品
                userDoc.cartList.forEach(item => {
                    if (item.productId == productId) {
                        userProductId = productId
                        item.productNum++
                    }
                })
                if (userProductId) {
                    //已添加的商品只增加数量
                    userDoc.save((err2, doc2) => {
                        if (err2) {
                            res.json({
                                status: -1,
                                msg: err2.message
                            })
                        } else {
                            res.json({
                                status: 0,
                                msg: '操作成功',
                                result: ''
                            })
                        }
                    })
                } else {
                    //未添加的查询goods表信息
                    goods.findOne({productId: productId}, (err3, goodsDoc) => {
                        if (err3) {
                            res.json({
                                status: -1,
                                msg: err3.message
                            })
                        } else {
                            if (goodsDoc) {
                                //查出来的信息赋值给user表的cartList
                                goodsDoc.productNum = 1
                                goodsDoc.checked = 1
                                userDoc.cartList.push(goodsDoc)
                                userDoc.save((err4, doc4) => {
                                    if (err4) {
                                        res.json({
                                            status: -1,
                                            msg: err2.message
                                        })
                                    } else {
                                        res.json({
                                            status: 0,
                                            msg: '操作成功',
                                            result: ''
                                        })
                                    }
                                })
                            }
                        }
                    })
                }
            }
        }
    })
})

7.删除购物车商品接口(mongoose删除用法)

router.post('/cartDel', (req, res, next) => {
    const userId = req.cookies.userId
    const productId = req.body.productId
    user.update({
            userId: userId
        },
        {
            //使用$pull
            $pull: {
                cartList: {
                    productId: productId
                }
            }
        }, (err, doc) => {
            if (err) {
                res.json({
                    status: -1,
                    msg: err.message
                })
            } else {
                if (doc) {
                    res.json({
                        status: 0,
                        msg: '删除成功',
                        result: ''
                    })
                }
            }
        })
})

8.修改购物车商品数据(mongoose修改数据用法)

router.post('/cartEdit', (req, res, next) => {
    const userId = req.cookies.userId,
        productId = req.body.productId,
        productNum = req.body.productNum,
        checked = req.body.checked
    user.update({
        userId: userId,
        'cartList.productId': productId
    }, {
        'cartList.$.productNum': productNum,
        'cartList.$.checked': checked
    }, (err, doc) => {
        if (err) {
            res.json({
                status: -1,
                msg: err.message
            })
        } else {
            if (doc) {
                res.json({
                    status: 0,
                    msg: '操作成功',
                    result: ''
                })
            }
        }
    })
})

//还可以使用findOne()+save()的方式来修改数据

mongodb数据库

  1. 安装mongodb数据库 安装教程
  2. 安装完成后启动mongodb(安装在腾讯云服务器了)
mongod -f /root/mongodb/etc/mongodb.conf  使用配置文件启动

此处有坑:如果需要mongodb常驻进程需要设置fork=true,否则在断开服务器连接后,数据库会关闭 3. 另起终端窗口,可以进行mongodb操作

mongo      进入mongodb操作模式
show dbs    查看数据库
use demo    选择数据库(没有的话创建)
db.dropDatabase()     删除数据库
show collections        查看集合
db.demo.drop()          删除集合
插入文档
db.createCollection('demo')     创建集合
db.demo.insert({id:123,name:'conan'})       创建并插入集合
更新文档
db.demo.update({id:'123',{$set:{name:'kids'}}})
db.demo.update({id:'123',{$set:{'class.name':'jd'}}})   更新子集字段
删除文档
db.demo.remove({id:123})
查询文档
db.demo.find()      查看集合
db.demo.find().pretty()     查看集合(格式化形式显示)
db.demo.findOne()       查看第一条集合的数据
db.demo.find({id:123})  按条件查询(findOne()同样用法)
db.demo.findOne({age:{$gt:20})  大于20($lt=>小于,$eq=>等于,$gte=>大于等于,$lte=>小于等于)