基于express、node与mongodb写后端接口
1、首先运行mongodb,建立一个数据库。(前提是你的电脑已经装了mongodb)
先打开一个命令窗口打开mongodb cd /usr/local
cd mongodb/bin
./mongod --dbpath=/Users/heyu/data
再打开一个命令窗口运行
mongodb cd /usr/local
cd mongodb/bin
./mongo
创建一个数据库 use xx(数据库名字)
2、创建express项目(基于 Node.js 平台,快速、开放、极简的 Web 开发框架)
npm / cnpm i express-generator -g express myapp --view=ejs (为什么要选ejs?因为ejs的语法和前端很像,容易看懂) cd myapp cnpm / npm i npm run start cnpm / npm i supervisor -g (安装supervisor依赖来监听代码的变化从而达到自动启动) 配置了dev指令 dev: supervisor ./bin/www
3、node 连接数据库
const mongoose = require('mongoose'); // 引入模块 const DB_URL = 'mongodb://localhost:27017/heyu'; // 数据库连接地址 // 连接数据库 // mongoose.connect(DB_URL); mongoose.connect(DB_URL, { useMongoClient: true }); // 数据库连接成功 mongoose.connection.on('connected', () => { console.log('数据库连接成功') }) // 数据库断开或者连接失败 mongoose.connection.on('disconnected', () => { console.log('数据库断开') }) // 数据库连接异常 mongoose.connection.on('error', () => { console.log('数据库连接异常') }) //将文件暴露出去 module.exports = mongoose;
4、封装公用的sql语句(难点)
const sql = { // 数据库集合靠函数去传递 insert (CollectionName, insertData) { // 数据库的操作属于异步操作,后续的业务逻辑会交给执行的那个单位 // A 调用了B B包含异步操作,操作完毕 A继续执行业务逻辑 // 异步操作 --- 回调函数 / promise / generator + yeild / async + await // User.insertMany(insertData, (err) => { // if (err) throw err; // console.log('插入成功') // }) // promise的写法 // return new Promise((resolve, reject) => { // }) return new Promise((resolve, reject) => { CollectionName.insertMany(insertData, (err) => { console.log('insertData',insertData) if (err) throw err; resolve() }) }) }, delete (CollectionName, deleteData, deleteType) { // User.deleteOne(deleteData, (err) => {}) // User.deleteMany(deleteData, (err) => {}) // style.display = "none" <===> style['display'] = "none" // style.animation = "test" 兼容性 // 对象后的属性不可以是变量,如果有变量,写成 对象[属性] 形式 deleteType = deleteType || 'deleteOne' // 默认为删除单条数据 return new Promise((resolve, reject) => { CollectionName[deleteType](deleteData, (err) => { if (err) throw err; resolve() }) }) }, update (CollectionName, whereObj, updateObj, updateType) { updateType = updateType || 'updateOne' return new Promise((resolve, reject) => { CollectionName[updateType](whereObj, updateObj, (err) => { if (err) throw err; resolve() }) }) }, find (CollectionName, whereObj, showObj) { return new Promise((resolve, reject) => { CollectionName.find(whereObj, showObj).exec((err, data) => { if (err) throw err; resolve(data) }) }) }, paging (CollectionName, whereObj, showObj, limitNum, pageCode) { return new Promise((resolve, reject) => { // limit(limitNum) 每页显示个数 // skip(limitNum * pageCode) // 每页从哪一个开始 CollectionName.find(whereObj, showObj).limit(limitNum).skip(limitNum * pageCode).exec((err, data) => { if (err) throw err; resolve(data) }) }) }, distinct(CollectionName, name) { return new Promise((resolve, reject) => { CollectionName.distinct(name).exec((err, data) => { if (err) throw err; resolve(data) }) }) } } module.exports = sql
5、建表。(我这里建立的是商品栏的表)
const mongoose = require('./../db.js'); // 引入数据库连接模块 const Schema = mongoose.Schema; // 拿到当前数据库相应的集合对象 // 设计用户表的集合 const proSchema = new Schema({ // 设计用户集合的字段以及数据类型 proid: {type: String }, // 商品id type: { type: String }, // 类型 brand: { type: String }, // 品牌 barndimg: { type: String }, // 品牌图片 proname: { type: String }, // 商品标题 price: { type: Number }, // 商品价格 flag: { type: Number }, // 是否推荐 proimg: { type: String }, // 商品图片 note: { type: String }, // 商品详情 postage: { type: String } // 包邮吗 }) module.exports = mongoose.model('Pro', proSchema);
6、app.js中配置好需要的依赖,将一些接口暴露出来
var createError = require('http-errors'); var express = require('express'); var path = require('path'); var cookieParser = require('cookie-parser'); var logger = require('morgan'); var jwt = require('jsonwebtoken'); var indexRouter = require('./routes/index'); var proRouter = require('./routes/pro'); cors = require('cors') var app = express(); app.use((cors()))//解决跨域 // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'ejs'); app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/pro', proRouter);//商品接口 // catch 404 and forward to error handler app.use(function(req, res, next) { next(createError(404)); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;
7、先将数据导入到数据库。(excel->mongodb)
var express = require('express'); var xlsx = require('node-xlsx'); var uuid = require('node-uuid'); var Pro = require('./../sql/collection/pros'); var sql = require('./../sql'); var router = express(); var filestr = '/Users/heyu/Desktop/project/mongdb/excel/shop.xlsx'; router.get('/import',(req,res,next) =>{ let obj = xlsx.parse(filestr)[0].data let arr = [] obj.map((item,index) =>{ if(index !== 0){ arr.push({ proid:"pro_" + uuid.v1(), type:item[0], brand:item[1], barndimg:item[2], proname:item[3], price:item[4], flag:item[5], proimg:item[6], note:item[7], postage:item[8] }) } }) sql.insert(Pro,arr).then(()=>{ res.send(arr) }) })
7、开始写接口
var express = require('express'); var xlsx = require('node-xlsx'); var uuid = require('node-uuid'); var Pro = require('./../sql/collection/pros'); var sql = require('./../sql'); var router = express(); var filestr = '/Users/heyu/Desktop/project/mongdb/excel/shop.xlsx'; router.get('/',function(req,res,next){ let{pageCode,limitNum} = req.query; pageCode = pageCode * 1 || 0; limitNum = limitNum * 1 || 10; sql.paging(Pro,{},{_id:0},limitNum,pageCode).then(data =>{ res.send({ code:'200', success:'查询列表成功', length:data.length, data:data }) }) }); //获取商品详情 router.get('/detail',(req,res,next) =>{ let{proid} = req.query sql.find(Pro,{proid},{_id:0}).then(data =>{ res.send({ code:'200', message:'查询该数据成功', data:data[0] }) }) }) //获取某一类 router.get('/type',(req,res,next) => { let {type} = req.query type = type ||'type' sql.distinct(Pro,type).then(data =>{ res.send({ code:'200', success:'获取类型成功', data:data }) }) }); // 新增 router.post('/insert',(({body}, res, next) => { body.proid = "pro_" + uuid.v1() sql.insert(Pro,body).then((data)=>{ res.send({ code: '200', message: '插入成功', data: data }) }).catch(e=>{ console.log(e) }) })) // 获取分类类型对应的品牌 router.get('/category', (req, res, next) => { let { type } = req.query sql.find(Pro, { type }, {_id: 0, brand:1, barndimg: 1}).then(data => { // 数组去重 https://www.cnblogs.com/le220/p/9130656.html let obj = {} // 利用reduce方法遍历数组,reduce第一个参数是遍历需要执行的函数,第二个参数是item的初始值 data = data.reduce((item, next) => { obj[next.brand] ? '' : obj[next.brand] = true && item.push(next) return item }, []) res.send({ code: '200', message: '获取分类类型列表', data: data }) }) }) // 获取品牌类型对应的产品 router.get('/brandcategory', (req, res, next) => { let { brand } = req.query sql.find(Pro, { brand: brand }, {_id: 0}).then(data => { res.send({ code: '200', message: '获取品牌分类列表', data: data }) }) }) // 搜索 router.get('/search', (req, res, next) => { let { text } = req.query sql.find(Pro, { proname: eval('/' + text + '/') }, {_id: 0}).then(data => { res.send({ code: '200', message: '搜索列表', data: data }) }) }) module.exports = router;
目录如下
长风破浪会有时,直挂云帆济沧海