Mongoose在Express、Koa、 Egg中的使用对比

411 阅读5分钟

Mongoose是什么?

简单一句话概括:Mongoose是一套操作MongoDB数据库的接口。

开始

在使用mongoose之前,需要事先安装好Node环境MongoDB数据库

以上准备就绪我们就可以了。

在Express Koa Egg中的使用

在Express中

首先初始化项目

npm init //初始化项目
npm i xxx --save//安装各种依赖例如express nodemon ...

目录如下

|-express
|  | -- db//启动mongodb数据库的dbpath路径
|  | --model//数据库中表的模型
|  | --node_modules
|  | --public//公共资源
|  | --route//路由
|  | --schema//模式类型
|  | --app.js//入口文件
|  | --package.json//配置文件

安装mongoose。

npm install mongoose//安装mongoose

在package.json

{
  "dependencies": {
    "body-parser": "^1.19.0",
    "connect-multiparty": "^2.2.0",
    "express": "^4.17.1",
    "formidable": "^1.2.2",
    "http-proxy-middleware": "^2.0.0",
    "mongoose": "^5.12.13",
    "multer": "^1.4.2",
    "multiparty": "^4.2.2",
    "nodemon": "^2.0.7",
    "xlsx": "^0.17.4"
  }
}

在app.js中引入依赖

const express=require("express");//引入express
const mongoose = require('mongoose');//引入mongoose
const app=express();
const port=8080;//端口号
mongoose.connect('mongodb://localhost:27017/Management',{useNewUrlParser:true,useUnifiedTopology:true},function(err){
    if(err){
        console.log('链接失败');
    }else{
        console.log('链接成功');   
    }
});//链接数据库名Mangagement端口号27017,取消数据库启动警告,

app.listen(port,()=>{
        	console.log(`Example app listening at http://localhost:${port}`)
        })

开启数据库 在安装mongodb/bin目录执行cdm 执行如下指令

$ mongod  --dbpath="数据库路径" --port=端口号
//例如
$ D:\Mongodb\bin> mongod  --dbpath="E:\myNode\Management\db" --port=27021

然后再E:\myNode\Management执行

nodemon app.js//如果成功控制台会打印
链接成功
Example app listening at http://localhost:8080
//说明数据库链接成功

链接成功我们可以对MongoDB数据库进行CURD操作

在schema文件夹下定义数据表模式类型

在schema/user.js

const mongoose=require('mongoose');
module.exports=new mongoose.Schema({
	Mailbox:String,
	UserName:String,
	Password:String,
	Password01:String,
	Name:String,
	Phone:Number,
	ContactAddress:String,
	Passport:String,
	ID:Number,
	Company:String,
	TouristGuide:String,
	GoAbroad:String
})

在model文件夹定义数据表模型

const mongoose=require('mongoose');
const userSchema=require('../schema/user.js')
module.exports=mongoose.model('User',userSchema)
//定义数据表名为User但是mongodb中的数据表名是Users

在route文件夹下定义路由

const express=require('express');
const multipart = require('connect-multiparty');//
const XLSX=require("xlsx")//读取elsx文件
const multipartMiddleware = multipart();

const router=express.Router();
const User=require('../model/user.js')
let userData;
router.use((req,res,next)=>{
	UserData={
		code:0,
		data:{},
		message:""
	}
	next();
})
//上传excal表
router.post('/uploadFile', multipartMiddleware, async function (req, res, next) {
	console.log("成功")
	console.log(req.files.file.path)
   let excelData = [];   //用来保存
   let reqData = [];
   const workbook = XLSX.readFile(req.files.file.path);//读取文件
   console.log(workbook)
  
   const sheetNames = workbook.SheetNames;//[sheet1]
  for (var sheet in workbook.Sheets) {
	  console.log(sheet)
    if (workbook.Sheets.hasOwnProperty(sheet)) {
      fromTo = workbook.Sheets[sheet]['!ref'];
	  console.log(workbook.Sheets[sheet])
	  console.log(fromTo)
      //解析excel文件得到数据
      excelData = excelData.concat(XLSX.utils.sheet_to_json(workbook.Sheets[sheet]));
    }
  }
  //excel表日期处理方法
  function excelDateFN(DataStr){
	  var y = new Date(1900, 0, DataStr)
	  var d=new Date(y)
	  var m=d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate() 
	  //+ ' ' + d.getHours() + ':' + d.getMinutes() + ':' + d.getSeconds(); 
	  return m
  }
   console.log(excelData);
  for (var i = 0; i < excelData.length; i++) {
    reqData.push({
      id: excelData[i]['编号'],
      Name: excelData[i]['姓名'],
      Sex: excelData[i]['性别'],
      EName: excelData[i]['英文名'],
      Nationality: excelData[i]['国籍'],
      BirthPlace: excelData[i]['出生地点'],
	  BirthDay: excelDateFN(excelData[i]['出生日期']),
      Passport: excelData[i]['护照号'],
	  DateIssue: excelDateFN(excelData[i]['护照签发日期']),
	  PeriodValidity: excelDateFN(excelData[i]['护照有效期']),
	  PlaceIssue: excelData[i]['护照签发地'],	 
      Visa: excelData[i]['签证号码'],
    })
  }
  //数据处理结束调用sql语句,并且返回前台
   console.log(reqData);
   if(reqData.length!=0){
	   UserData.code=1;
	   UserData.message="上传成功";
	   UserData.data=reqData
	   res.send(UserData)
   }else{
	   UserData.code=1;
	   UserData.message="上传失败";
	   UserData.data=""
	   res.send(UserData)
   }
  //res.json(reqData)
  
   
})

//信息展示
router.post("/personalData",(req,res)=>{
	const UserName=req.body.UserName
	
	User.findOne({UserName:UserName}).then((data)=>{
		if(data){
			UserData.code=1;
			UserData.message="请求成功";
			UserData.data=data
			res.send(UserData)
		}
		
	})
	
})
//修改信息
router.post("/revisePersonalData",(req,res)=>{
	console.log(req.body)
	const _id=req.body._id,
		UserName=req.body.UserName,
		Password=req.body.Password,
		Password01=req.body.Password01,
		Name=req.body.Name,
		Phone=req.body.Phone,
		ContactAddress=req.body.ContactAddress,
		Passport=req.body.Passport,
		ID=req.body.ID,
		Company=req.body.Company
	const updateFields = {
					_id,
					UserName,
					Password,
					Password01,
					Name,
					Phone,
					ContactAddress,
					Passport,
					ID,
					Company
							};
	User.findByIdAndUpdate({_id:_id},updateFields,(err,data)=>{
		if(data){
			UserData.code=1;
			UserData.message="修改成功";
			
			res.send(UserData)
		}
	})
	
	  
})
//注册
router.post('/logon',(req,res)=>{
		const UserName=req.body.UserName
		const Password=req.body.Password
		const Password01=req.body.Password01
		const Name=req.body.Name
		const Phone=req.body.Phone
		const ContactAddress=req.body.ContactAddress
		const Passport=req.body.Passport
		const ID=req.body.ID
		const Company=req.body.Company
	//console.log(req.body)
	User.findOne({UserName:UserName}).then(function(data){
		console.log(data)
		if(data){
			UserData.code=3;
			UserData.message="用户名已存在";
			res.send(UserData)
		}else{
			let newUser=new User({
				UserName:UserName,
				Password:Password,
				Password01:Password01,
				Name:Name,
				Phone:Phone,
				ContactAddress:ContactAddress,
				Passport:Passport,
				ID:ID,
				Company:Company,	
			})
			 newUser.save()
			 UserData.code=1;
			 UserData.message="注册成功";
			 res.send(UserData)
		}
	})
	
})
//登录
router.post('/register',(req,res)=>{
	let userName=req.body.userName;
	let password=req.body.passWord;
	 console.log(req.body)
	User.find({UserName:userName,Password:password}).then((data)=>{
		console.log(data)
		if(data){
			console.log('登录成功')
			UserData.code=1
			UserData.message="登录成功"
			res.send(UserData)
		}else{
			console.log('登录成功')
			UserData.code=2
			UserData.message="用户名不存在"
			res.send(UserData)
		}
	})
	
})
module.exports=router

在app.js中使用路由

app.use('/User',require('./route/user.js'))

接口:

注册:http://localhost:8080/User/login

登录:http://localhost:8080/User/register

上传:http://localhost:8080/User/uploadFile

查找:http://localhost:8080/User/personalData

修改:http://localhost:8080/User/revisePersonalData

在Koa中

首先初始化项目

npm init //初始化项目
npm i xxx --save//安装各种依赖例如koa nodemon ...

目录如下

|-koa
|  | -- db//启动mongodb数据库的dbpath路径
|  | --model//数据库中表的模型
|  | --node_modules
|  | --public//公共资源
|  | --route//路由
|  | --schema//模式类型
|  | --app.js//入口文件
|  | --package.json//配置文件

安装mongoose。

npm install mongoose//安装mongoose

在package.json

{
  "name": "vietnam",
  "version": "1.0.0",
  "description": "越南签证管理系统的接口项目",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "start": "node app.js"
  },
  "author": "木西",
  "license": "ISC",
  "dependencies": {
    "@koa/multer": "^3.0.0",
    "koa": "^2.13.1",
    "koa-body": "^4.2.0",
    "koa-bodyparser": "^4.3.0",
    "koa-router": "^10.0.0",
    "koa-static": "^5.0.0",
    "koa2-cors": "^2.0.6",
    "mongodb": "^4.0.1",
    "mongoose": "^5.13.5",
    "multer": "^1.4.2",
    "path": "^0.12.7"
  },
  "devDependencies": {}
}


在app.js中引入依赖

const Koa=require('koa');
const cors = require('koa2-cors');//跨域的包
const mongoose=require('mongoose');
const router=require('koa-router')()//路由
const koaStatic=require('koa-static')//静态
const koaBody=require('koa-body');//
const multer = require('@koa/multer');
const bodyParser=require('koa-bodyparser')//post请求
const path=require('path');
const app=new Koa();


var storage = multer.diskStorage({
    //文件保存路径
    destination: function(req, file, cb) {
        cb(null,path.join(__dirname ,'/public/uploads'))
    },
    //修改文件名称
    filename: function(req, file, cb) {
		let type = file.originalname.split('.')[1]
		cb(null, `${file.fieldname}-${Date.now().toString(16)}.${type}`)
    }
})
//加载配置
//

var upload = multer({storage});
router.post('/upload',upload.single('File'), async(ctx, next) => {
	console.log(ctx.request)
ctx.body = `${ctx.origin}/public/uploads/${ctx.file.filename}`
})

let register=require('./routes/register.js')
let vise=require('./routes/visa.js')
let DataList=require('./routes/datalist.js')
router.use(register.routes())//登录接口
router.use(vise.routes())//签证接口
router.use(DataList.routes())
app.use(cors())//允许跨域

app.use(bodyParser())//启用bodyParser解决post请求
app.use(router.routes())//启用路由
app.use(router.allowedMethods()) 
mongoose.connect('mongodb://localhost:27018/VietNam',{useNewUrlParser:true,useUnifiedTopology:true},(err)=>{
    if(err){
        console.log('链接失败');
    }else{
        console.log('链接成功');	
		{
			//创建新表
			//const dataList=mongoose.model('数据表名',{"健名":类型})
			//const kitty = new dataList({"键名":"键值"})
			//kitty.save().then(() => console.log('我是创建数据新表'));
		}
		
	};
	})//数据表名VietNam端口号27018取消数据库启动警告
app.listen(3001,()=>{
	console.log('http://localhost:3001')
});

开启数据库 在安装mongodb/bin目录执行cdm 执行如下指令

$ mongod  --dbpath="数据库路径" --port=端口号
//例如
$ D:\Mongodb\bin> mongod  --dbpath="E:\myNode\VietNam\db" --port=27018

然后再E:\myNode\Management执行

nodemon app.js//如果成功控制台会打印
链接成功
http://localhost:3001
//说明数据库链接成功

链接成功我们可以对MongoDB数据库进行CURD操作

在schema文件夹下定义数据表模式类型

在schema/user.js

//和express使用方法一样
const mongoose=require('mongoose');
module.exports=new mongoose.Schema({
	UserName:String,
	Password:String,
})

在model文件夹定义数据表模型

//和express使用方法一样
const mongoose=require('mongoose');
const userSchema=require('../schema/user.js')
module.exports=mongoose.model('User',userSchema)
//定义数据表名为User但是mongodb中的数据表名是Users

在route文件夹下定义路由

const Router=require('koa-router');
const router=new Router();
const Visa=require('../model/visa.js');
router.post('/visa',async (ctx,next)=>{
	console.log(ctx.request.body.ID)
	ctx.response.status=200
	let VisaU= await Visa.find({"ID":ctx.request.body.ID})
	const obj={
		detail:[]
	}
	let User=VisaU[0]	
	console.log(User)
	if(User===undefined){
		//obj.msg="该订单不存在"
		ctx.body=obj
	}else{
		//obj.msg="查询成功"
		obj.detail=User
		ctx.body=obj
		
	}
	//ctx.body=User
})
module.exports=router

在app.js中使用路由

let vise=require('./routes/visa.js')
router.use(vise.routes())//签证接口

接口:

签证:http://localhost:8080/visa

在Egg中

首先初始化初始化项目

$ mkdir project-name//创建一个空的文件夹
$ npm init egg --type=simple//simple表示骨架类型

目录如下:

|-app//主要开发的文件
|   |-- controller//解析用户的输入,处理后返回相应的结果
|   |-- db//启动mongodb数据库的dbpath路径(可选)
|   |--extend//框架的扩展(内置对象扩展)
|   |    |---application.js//(固定名称)
|   |    |---context.js//(固定名称)
|   |    |---request.js//(固定名称)
|   |    |---response.js//(固定名称)
|   |    |---helper.js//(固定名称)
|   |--middleware//编写中间件
|   |--model//数据库中表的模型
|   |--publie//静态资源
|   |--schedule//定时任务
|   |--service//编写业务逻辑层
|   |--view//模板文件
|   |---router.js//配置 URL 路由
|-config//存放配置文件
|   |--config.default.js//用于编写配置文件
|   |--plugin.js//配置需要加载的插件
|-test//存放单元测试
|-logs//日志文件
|-package.json//项目描述

下载egg-mongoose

npm i egg-mongoose --save

配置config/plugin.js

'use strict';
module.exports = {
  mongoose:{
     enable:true,
     package:"egg-mongoose" 
  }
};

在config/config.default.js

'use strict';
module.exports = appInfo => {
  const config = exports = {};
  // use for cookie sign key, should change to your own and keep security
  config.keys = appInfo.name + '_1641975352438_173';
  // add your middleware config here
  config.middleware = [];
  // add your user config here
  const userConfig = {
    // myAppName: 'egg',
  };
 
 //mongoose数据库配置
  config.mongoose={
      url:'mongodb://127.0.0.1:27021/VietNamVisa',//端口号27021数据库名VietNamVisa
      options:{useNewUrlParser:true,useUnifiedTopology:true},//其他配置警告解除方法
  }

  return {
    ...config,
    ...userConfig,
  };
};

开启数据库

打开电脑上的mongodb文件夹下的bin目录cmd

执行如下指令

mongod --dbpath=存储数据的路径 --port=数据库的端口号

例如

mongod  --dbpath=E:\myNode\VietNamVisa\init\app\db    --port=27021

然后再E:\myNode\VietNamVisa执行

 npm run dev//启动项目

在app/model/visaOnArrivalModel.js

创建一个模型

module.exports=app=>{
    const {mongoose}=app;
    const {Schema}=mongoose;
    const VisaOnArrivalSchema=new Schema({
        //订单号
        OrderNumber:{type:String},
        //姓名
        FullName:{type:String},
        //护照号
        PassportNo:{type:String},
        //出发航班号
        DepartureFlightNumber:{type:String},
        //入境时间
        TimeOfEntry:{type:String},
        //抵达机场
        ArriveAtTheAirport:{type:String},
        //航班号
        FlightNumber:{type:String},
        //英文名
        EnglishName:{type:String},
        //性别
        Gender:{type:String},
        //出生日期
        DateOfBirth:{type:String},
        //国籍
        Nationality:{type:String},
        //护照签发日期
        PassportIssueDate:{type:String},
        //护照有效期
        PassportPeriodOfValidity:{type:String},
        //离境日期
        DepartureDate:{type:String},
        //出发城市
        DepartureCity:{type:String},
        //批文类型
        Type:{type:String},
        //批文的状态
        Status:{type:String},
        //Checked:{type:Boolean}
    });
    return mongoose.model("VisaOnArrivalModel",VisaOnArrivalSchema,"visaonarrivals")
    }
//定义了一张名为visaonarrivals的数据表

在app/service/visaOnArrivalService.js

编写操作数据库的业务逻辑

"use strict"
const Service=require("egg").Service;
class VisaOnArrivalService extends Service {
    async VisaOnArrival(obj){
        const {ctx}=this;
        
            //存储数据
            //注意!!!!ctx.model.xxx中xxx指的是model的文件名首字母大写
         const VisaOnArrivalList = new ctx.model.VisaOnArrivalModel({
                        OrderNumber:obj.OrderNumber,
                         //姓名
                        FullName:obj.FullName,
                        //护照号
                        PassportNo:obj.PassportNo,
                        //出发航班号
                        DepartureFlightNumber:obj.DepartureFlightNumber,
                        //入境时间
                         TimeOfEntry:obj.TimeOfEntry,
                        //抵达机场
                        ArriveAtTheAirport:obj.ArriveAtTheAirport,
                        //航班号
                        FlightNumber:obj.,
                        //英文名
                         EnglishName:obj.FlightNumber,
                         //性别
                         Gender:obj.Gender,
                        //出生日期
                        DateOfBirth:obj.DateOfBirth,
                         //国籍
                         Nationality:obj.Nationality,
                        //护照签发日期
                         PassportIssueDate:obj.PassportIssueDate,
                         //护照有效期
                        PassportPeriodOfValidity:obj.PassportPeriodOfValidity,
                         //离境日期
                         DepartureDate:obj.DepartureDate,
                       //出发城市
                         DepartureCity:obj.DepartureCity,
                         //类型
                         Type:obj.Type,
                         //批文的状态
                        Status:obj.Status,              
                     });
                   // 数据保存到数据库
                    VisaOnArrivalList.save();
                    return "添加成功"
                    }
    
}
module.exports=VisaOnArrivalService;

在app/controller/visaOnArrival.js

编写关于解析用户的输入,处理后返回相应的结果

"use strict"
const Controller=require('egg').Controller;
class VisaOnArrival extends Controller {
    async VisaOnArrival(){
        const {ctx}=this
        //const req=ctx.request.body
        const res=await ctx.service.visaOnArrivalService.VisaOnArrival(req)
        //console.log(res)
        ctx.body={
            state:200,
            msg:res
        }
    }
}
module.exports=VisaOnArrival

在app/router.js

编写路由

'use strict';
module.exports = app => {
  const { router, controller } = app;
 //添加数据
  router.post("/AddVisaOnArrival",controller.visaOnArrival.VisaOnArrival);
};

总结

以上就是关于Mongoose在Express、Koa、 Egg中使用对比,Mongoose在Express、Koa的使用没有区别。在 Egg中的使用相较与另外两个框架有较大的改动。最大的区别还是基于框架自身特点。前两个框架没有太多约定,写法比较自由随性,完全根据开发者自己的喜好编写。Egg的特点约定优于配置。开发者书写就更加规范统一。