Node.js详解之npm、express框架、MongoDB——part02

01包管理工具

1.概念介绍

1.1 包是什么

『包』英文单词是 package ,代表了一组特定功能的源码集合

1.2 包管理工具

管理『包』的应用软件,可以对「包」进行 下载安装 , 更新 , 删除 , 上传 等操作
借助包管理工具,可以快速开发项目,提升开发效率
包管理工具是一个通用的概念,很多编程语言都有包管理工具,所以 掌握好包管理工具非常重要

1.3 常用的包管理工具

下面列举了前端常用的包管理工具

  • npm
  • yarn
  • cnpm

2.npm

npm 全称 Node Package Manager ,翻译为中文意思是『Node 的包管理工具。
npm 是 node.js 官方内置的包管理工具,是 必须要掌握住的工具。

2.1 npm 的安装

node.js 在安装时会 自动安装 npm ,所以如果你已经安装了 node.js,可以直接使用 npm。可以通过 npm -v 查看版本号测试,如果显示版本号说明安装成功,反之安装失败。
在这里插入图片描述

2.2 npm 基本使用

2.2.1 初始化

创建一个空目录,然后以此目录作为工作目录 启动命令行工具 ,执行 npm init
在这里插入图片描述
package.json文件内容展示:
在这里插入图片描述
npm init 命令的作用是将文件夹初始化为一个『包』, 交互式创建 package.json 文件。
package.json 是包的配置文件,每个包都必须要有 package.json。
属性翻译:

{
"name": "1-npm", #包的名字
"version": "1.0.0", #包的版本
"description": "", #包的描述
"main": "index.js", #包的入口文件
"scripts": { #脚本配置
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "", #作者
"license": "ISC" #开源证书
}

注意事项

1.package name ( 包名 ) 不能使用中文、大写,默认值是 文件夹的名称 ,所以文件夹名称也不能使用中文和大写
2.version ( 版本号 )要求 x.x.x 的形式定义, x 必须是数字,默认值是 1.0.0
3.ISC 证书与 MIT 证书功能上是相同的,关于开源证书扩展阅读http://www.ruanyifeng.com/blog/2011/05/how_to_choose_free_software_licenses.html
4.package.json 可以手动创建与修改
5.使用 npm init -y 或者 npm init --yes 极速创建 package.json

2.2.2 搜索包

搜索需要使用的包的方式有两种

  1. 命令行 『npm s/search 关键字』
    在这里插入图片描述
  2. 网站搜索 网址是 https://www.npmjs.com/在这里插入图片描述
2.2.3安装包

通过npm installnpm i 命令安装包(这是局部安装,只能在安装此依赖的目录下使用,出了该目录就使用不了了)
示例:npm i uniq
安装完成后使用包:
1.导入包 const uniq = require(‘uniq’)
2.使用:console.log(uniq(arr))

2.3生产依赖和开发依赖

在安装时可以选择要安装的依赖的类型:

类型命令补充
生产依赖npm i -S uniq或npm i --save uniq-S等效于–save,-S是默认选项,包信息保存在package.json中dependencies属性中
开发依赖npm i -D less或npm i --save-dev less-D等效于–save-dev,包信息保存在package.json中devDependencies属性中

2.4全局安装

我们可以执行安装选项-g 进行全局安装,局部安装的依赖通过require来使用,全局安装的依赖通过命令行来使用。

npm i -g nodemon

全局安装完成之后就可以在命令行的任何位置运行 nodemon 命令。
该命令的作用是 自动重启 node 应用程序。

1.全局安装的命令不受工作目录位置影响
2.可以通过 npm root -g 可以查看全局安装包的位置
3.不是所有的包都适合全局安装 , 只有全局类的工具才适合,可以通过查看包的官方文档来确定

2.5安装包依赖

在项目协作中有一个常用的命令就是 npm i ,通过该命令可以依据 package.json 和 package
lock.json的依赖声明安装项目依赖。(在刚进入到一个项目拉取下来代码之后,首先需要进行npm i来安装代码需要使用到的所有依赖)

2.6安装指定版本的包和删除依赖

安装

npm i 包名@版本号
npm i jquery@1.11.2

删除

局部删除
npm remove uniq
全局删除
npm remove -g nodemon

2.7npm配置命令别名

通过配置命令别名可以更简单的执行命令
配置 package.json 中的 scripts 属性

{
 .
 .
 "scripts": {
 "server": "node server.js",
 "start": "node index.js",
 },
 .
 .
}

配置完成之后,可以使用别名执行命令

npm run server
npm run start   //start比较特别,可以省略run,直接  npm start

补充说明:
npm start 是项目中常用的一个命令,一般用来启动项目
npm run 有自动向上级目录查找的特性,跟 require 函数也一样
对于陌生的项目,我们可以通过查看 scripts 属性来参考项目的一些操作

3.cnpm

3.1介绍

cnpm 是一个淘宝构建的 npmjs.com 的完整镜像,也称为『淘宝镜像』,网址https://npmmirror.com/
cnpm 服务部署在国内 阿里云服务器上 , 可以提高包的下载速度
官方也提供了一个全局工具包 cnpm ,操作命令与 npm 大体相同

3.2安装

通过npm来安装cnpm

npm install -g cnpm --registry=https://registry.npmmirror.com

3.3操作命令

功能命令
初始化cnpm init
安装包1.cnpm i uniq 2.cnpm i -S uniq 3.cnpm i -D uniq 4.cnpm i -g nodemon
安装项目依赖cnpm i
删除cnpm r uniq

3.4npm配置淘宝镜像

用 npm 也可以使用淘宝镜像,配置的方式有两种
直接配置
使用如下命令即可完成配置

npm config set registry https://registry.npmmirror.com/

工具配置
1.安装nrm

npm i -g nrm

2.修改镜像

nrm use taobao

3.检查是否配置成功

npm config list

4.yarn

4.1yarn介绍

yarn 是由 Facebook 在 2016 年推出的新的 Javascript 包管理工具,官方网址:https://yarnpkg.com/

4.2yarn特点

yarn 官方宣称的一些特点
速度超快:yarn 缓存了每个下载过的包,所以再次使用时无需重复下载。 同时利用并行下载以最大
化资源利用率,因此安装速度更快
超级安全:在执行代码之前,yarn 会通过算法校验每个安装包的完整性
超级可靠:使用详细、简洁的锁文件格式和明确的安装算法,yarn 能够保证在不同系统上无差异的工作

4.3yarn的安装以及常用命令

安装

npm i -g yarn

常用命令

功能命令
初始化yarn init/yarn init -y
安装包yarn add uniq 生产依赖 yarn addless --dev 开发依赖 yarn global add nodemon 全局安装
删除包yarn remove uniq 删除项目依赖包 yarn global remove nodemon 全局删除包
安装项目依赖yarn
运行命令别名yarn 别名(不需要添加run)
查看yarn全局安装包的位置yarn global bin

注意:这里有个小问题就是 全局安装的包不可用 ,yarn 全局安装包的位置可以通过 yarn lobal bin来查看,然后将该位置配置到环境变量中即可使用。

4.4yarn配置淘宝镜像

可以使用如下命令配置yarn的淘宝镜像

yarn config set registry https://registry.npmmirror.com/

可以通过 yarn config list 查看 yarn 的配置项
注意包管理工具不要混着用

5.nvm

介绍
vm 全称 Node Version Manager 顾名思义它是用来管理 node 版本的工具,方便切换不同版本的Node.js
下载安装
首先先下载 nvm,下载地址 https://github.com/coreybutler/nvm-windows/releases,选择 nvm-setup.exe 下载即可
常用命令

命令说明
nvm list available显示所有可以下载的Node.js版本
nvm list显示已安装的版本
nvm install 16.18.0安装16.18.0版本的Node.js(下载完后需要使用)
nvm install latest安装最新版本的Node.js
nvm uninstall 16.18.0删除某个版本的Node.js
nvm use 16.18.0切换16.18.0的Node.js

02express框架

2.1介绍

express 是一个基于 Node.js 平台的极简、灵活的 WEB 应用开发框架,官方网址:https://www.expressjs.com.cn/
简单来说,express 是一个封装好的工具包,封装了很多功能,便于我们开发 WEB 应用(HTTP 服务)
在这里插入图片描述

2.2使用

下载安装

npm init
npm i express

使用步骤

// 导入express
const express = require('express')
// 创建应用对象
const app = express()
// 创建路由
app.get('/',(req,res)=>{
    res.end("hello")
})
// 监听端口,启动服务
app.listen(8000,()=>{
    console.log("服务已经启动,8000端口正在监听中......")
})

命令行下执行该脚本

node xxx.js
或者
nodemon xxx.js

2.3路由

路由确定了应用程序如何响应客户端对特定端点的请求。
路由的使用
一个路由的组成有请求方法、 路径和回调函数组成。
express 中提供了一系列方法,可以很方便的使用路由,使用格式如下:

app.<method>(path,callback) 
// 导入express
const express = require('express')
// 创建应用对象
const app = express()
// 创建路由1
app.get('/hello', (req, res) => {
    res.end("hello")
})
// 创建路由2
app.post('/world', (req, res) => {
    res.end("world")
})
//匹配所有的请求方法 路由3
app.all('/search', (req, res) => {
    res.send('1 秒钟为您找到相关结果约 100,000,000 个');
})
//自定义 404 路由(以上路由均匹配不到时,响应这个路由)
app.all("*", (req, res) => {
    res.send('<h1>404 Not Found</h1>')
})
// 监听端口,启动服务
app.listen(8000, () => {
    console.log("服务已经启动,8000端口正在监听中......")
})

2.4获取请求参数

express 框架封装了一些 API 来方便获取请求报文中的数据,并且兼容原生 HTTP 模块的获取方式

app.get('/hello', (req, res) => {
    //1. 获取报文的方式与原生 HTTP 获取方式是兼容的
    // console.log(req.method)
    // console.log(req.url)
    // console.log(req.httpVersion)
    // console.log(req.header)
    //2. express 独有的获取报文的方式
    //获取查询字符串
    console.log(req.query); // 『相对重要』
    // 获取指定的请求头
    console.log(req.get('host'));
    console.log(req.get('Connection'))
    res.end("hello")
})

2.5获取路由参数

路由参数指的是URL路径中的参数(数据)
在这里插入图片描述
在这里插入图片描述

app.get('/:xxx.html', (req, res) => {
 res.send('商品详情, 商品 id 为' + req.params.xxx);
});  //即可获取到

在这里插入图片描述

2.6express响应设置

// 导入express
const express = require('express')
// 创建应用对象
const app = express()
// 创建路由1
app.get('/hello', (req, res) => {
    //1. express 中设置响应的方式兼容 HTTP 模块的方式
    // res.statusCode = 404;
    // res.statusMessage = 'find fault';
    // res.setHeader('abc', 'xyz');
    // res.write('response');
    // res.end('HTTP');
    //2. express 的响应方法
     res.status(500); //设置响应状态码
     res.set('xxx', 'yyy');//设置响应头
     res.send('中文响应不乱码');//设置响应体
    //连贯操作
     res.status(404).set('xxx', 'yyy').send('你好朋友')
    //3. 其他响应
    res.redirect('http://www.baidu.com')//重定向
     res.download(__dirname + '/index.html');//下载响应
     res.json();//响应 JSON
     res.sendFile(__dirname + '/index.html') //响应文件内容

})
// 监听端口,启动服务
app.listen(8000, () => {
    console.log("服务已经启动,8000端口正在监听中......")
})

2.7中间件

2.7.1认识中间件

中间件(Middleware)本质是一个回调函数。
中间件函数可以像路由回调一样访问请求对象(request), 响应对象(response)。
作用中间件的作用就是使用函数封装公共操作,简化代码。
类型全局中间件和路由中间件

2.7.2全局中间件

定义全局中间件

let recordMiddleware = function(request,response,next){
 //实现功能代码
 //.....
 //执行next函数(当如果希望执行完中间件函数之后,仍然继续执行路由中的回调函数,必须调用next)
 next();
}
//应用中间件
app.use(recordMiddleware)

声明时可以直接将匿名函数传递给 use

app.use(function (request, response, next) {
 console.log('定义第一个中间件');
 next();
})

定义多个全局中间件

app.use(function (request, response, next) {
 console.log('定义第一个中间件');
 next();
})

app.use(function (request, response, next) {
 console.log('定义第二个中间件');
 next();
}) 

案例

// 导入express
const express = require('express')
const fs = require('fs')
const path = require('path')
// 创建应用对象
const app = express()
// 将每次的请求记录保存到文件request.log中
let recordMiddleware = function (request, response, next) {
    let { url, ip } = request
    //实现功能代码
    fs.appendFileSync(path.resolve(__dirname, './access.log'), `${url} ${ip}\r\n`)
    //执行next函数(当如果希望执行完中间件函数之后,仍然继续执行路由中的回调函数,必须调用next)
    next();
}
app.use(recordMiddleware)
// 创建路由1
app.get('/hello', (req, res) => {
    res.send('前台首页')
})
app.get('/home', (req, res) => {
    res.send('后台首页')
})
// 监听端口,启动服务
app.listen(8000, () => {
    console.log("服务已经启动,8000端口正在监听中......")
})

2.7.3路由中间件

如果 只需要对某一些路由进行功能封装 ,则就需要路由中间件
调用格式如下

let recordMiddleware1 = function(request,response,next){
 //实现功能代码
 //.....
 //执行next函数(当如果希望执行完中间件函数之后,仍然继续执行路由中的回调函数,必须调用next)
 next();
}
let recordMiddleware2 = function(request,response,next){
 //实现功能代码
 //.....
 //执行next函数(当如果希望执行完中间件函数之后,仍然继续执行路由中的回调函数,必须调用next)
 next();
}
app.get('/路径',recordMiddleware1,(request,response)=>{
 
});

app.get('/路径',recordMiddleware1,recordMiddleware2,(request,response)=>{
 
});

案例

// 导入express
const express = require('express')
const fs = require('fs')
const path = require('path')
// 创建应用对象
const app = express()
// 将每次的请求记录保存到文件request.log中
let recordMiddleware = function (request, response, next) {
    let { url } = request
    console.log(request)
    //实现功能代码
    fs.appendFileSync(path.resolve(__dirname, './access1.log'), `${url}\r\n`)
    //执行next函数(当如果希望执行完中间件函数之后,仍然继续执行路由中的回调函数,必须调用next)
    next();
}
// 创建路由1
app.get('/index', recordMiddleware,(req, res) => {

    res.send('前台首页')
})
app.get('/reg', (req, res) => {
    res.send('后台首页')
})
// 监听端口,启动服务
app.listen(8000, () => {
    console.log("服务已经启动,8000端口正在监听中......")
})

2.7.4静态资源中间件

//引入express框架

const express = require('express');

//创建服务对象

const app = express();

//静态资源中间件的设置,将当前文件夹下的public目录作为网站的根目录

app.use(express.static('./public')); //当然这个目录中都是一些静态资源

//如果访问的内容经常变化,还是需要设置路由

//但是,在这里有一个问题,如果public目录下有index.html文件,单独也有index.html的路由,

//则谁书写在前,优先执行谁

app.get('/index.html',(request,response)=>{
 respsonse.send('首页');
});

//监听端口
app.listen(8000,()=>{
 console.log('8000 端口启动....');
});

注意事项:
1.index.html 文件为默认打开的资源
2.如果静态资源与路由规则同时匹配,谁先匹配谁就响应
3.路由响应动态资源,静态资源中间件响应静态资源

2.8获取请求体数据body-parser

express可以使用body-parser包处理请求体
第一步:安装
npm i body-parser
第二步:导入body-parser包
const bodyParser = require('body-parser')
第三步:获取中间件函数
处理querstring格式的请求体: let urlParser = bodyParser.urlencoded({extended:false});
处理JSON格式的请求体:let jsonParser = bodyParser.json();
第四步:设置路由中间件,然后使用request.body来获取请求体数据
(中间件函数执行完之后就会给req身上添加上一个属性body,这样就可以获得请求体的内容了)

app.post('/login', urlParser, (request,response)=>{
 //获取请求体数据
 //console.log(request.body);
 //用户名
 console.log(request.body.username);
 //密码
 console.log(request.body.userpass); 
 response.send('获取请求体数据');
});

获取到的请求体数据
[Object: null prototype] { username: 'admin', userpass: '123456' }

2.9防盗链

设置防盗链的作用:防止本网站的资源被其他网站使用。通过请求头中的referer来检测。

  app.use((req,res,next)=>{
  //检测请求头中的referer是否为127.0.0.1(自己服务的hostname)
  //获取referer
  let referer = req.get('referer');
  if(referer){
    //实例化
    let url = new URL(referer);
    //获取hostname
    let hostname = url.hostname;
    //判断
    if(hostname!=='127.0.0.1'){
      //响应404
      res.status(404).send('<h1>404 Not Found</h1>');
      return
      }
    }
  next();
  })

2.10路由模块化——Router

什么是Router
express 中的 Router 是一个完整的中间件和路由系统,可以看做是一个小型的 app 对象。
作用
对路由进行模块化,更好的管理路由
使用
在这里插入图片描述

03EJS模板引擎

3.1什么是模板引擎

模板引擎是分离用户界面和业务数据的一种技术

3.2什么是EJS

EJS 是一个高效的 Javascript 的模板引擎
官网: https://ejs.co/
中文站:https://ejs.bootcss.com/

3.3EJS初体验

下载安装ejs
npm i ejs --save
实例代码1
<%= %> 是ejs解析内容的标记,作用是输出当前表达式的执行结构
在这里插入图片描述
实例代码2
列表渲染
<% code %> 执行JS代码
在这里插入图片描述

3.4在express中使用ejs

在这里插入图片描述

04express-generator

安装
npm i -g express-generator
创建
express -e 文件名
安装依赖
npm i
运行
npm start
formidable包可以处理文件请求
npm i formidable
在这里插入图片描述

05Mongodb

5.1下载与安装

下载链接:https://www.mongodb.com/try/download/community
在这里插入图片描述
在这里插入图片描述

5.2命令行交互

命令行交互一般是学习数据库的第一步,不过这些命令在后续用的比较少。
数据库命令
1.显示所有的数据库
show dbs
2.切换到指定的数据库,如果数据库不存在会自动创建数据库
use 数据库名
3.显示当前所在的数据库
db
4.删除当前数据库
use 库名
db.dropDataBase()
集合命令
1.创建集合
db.createCollection('集合名称')
2.显示当前数据库中的所有集合
show collections
3.删除某个集合
db.集合名.drop()
4.重命名集合
db.集合名.renameCollection('newname')
文档命令
1.插入文档
db.集合名.insert(文档对象)
db.集合名.insert({name:'张三'},{age:18})
2.查询文档
db.集合名.find(查询条件)
3.更新文档
db.集合名.update(查询条件,新的文档)
db.集合名.update({name:'张三'},{$set:{age:19}})
4.删除文档
db.集合名.remove(查询条件)
_id 是 mongodb 自动生成的唯一编号,用来唯一标识文档

5.3Mongoose

5.3.1介绍

Mongoose 是一个对象文档模型库,官网http://www.mongoosejs.net/

5.3.2作用

方便使用代码操作 mongodb 数据库

5.3.3使用流程

安装Mongoose
npm i mongoose

//1. 安装 mongoose

//2. 导入 mongoose
const mongoose = require('mongoose');

//3. 连接数据库
mongoose.connect('mongodb://127.0.0.1:27017/bilibili');

//4. 设置连接回调

//连接成功
mongoose.connection.on('open', () => {
 console.log('连接成功');
 //5. 创建文档结构对象
 let BookSchema = new mongoose.Schema({
  //title、author、price均为字段
 title: {
 type: String,
 required: true // 设置必填项
 },
 author: String,
 price: Number
 });
 
 //6. 创建文档模型对象(相当于创建book表)
 let BookModel = mongoose.model('book', BookSchema);
 
 //7. 插入文档
 BookModel.create({
 title: '西游记',
 author: '吴承恩',
 price: 19.9
 }, (err, data) => {
 if (err) throw err;
 //输出 data 对象
 console.log(data);
 
 //8. 断开连接
 mongoose.disconnect();
 });
});

//连接出错
mongoose.connection.on('error', () => {
 console.log('连接出错~~');
})

//连接关闭
mongoose.connection.on('close', () => {
 console.log('连接关闭');
})

5.3.4字段类型

类型描述
String字符串
Number数字
Boolean布尔值
Array数组,也可以使用 [] 来标识
Date日期
BufferBuffer 对象
Mixed任意类型,需要使用 mongoose.Schema.Types.Mixed 指定
ObjectId对象 ID,需要使用 mongoose.Schema.Types.ObjectId 指定
Decimal128高精度数字,需要使用 mongoose.Schema.Types.Decimal128 指定

5.3.5字段值验证

Mongoose 有一些内建验证器,可以对字段值进行验证
必填项

title: {
 type: String,
 required: true // 设置必填项
},

默认值

author: {
 type: String,
 default: '匿名' //默认值

},

枚举值

gender: {
 type: String,
 enum: ['男','女'] //设置的值必须是数组中的

},

唯一值

username: {
 type: String,
 unique: true
},

unique 需要 重建集合 才能有效果

5.3.6CURD

增删改查
增加
插入一条

SongModel.create({
 title:'给我一首歌的时间',
 author: 'Jay'
}, function(err, data){
 //错误
 console.log(err);
 //插入后的数据对象
 console.log(data);
});

批量插入

//1.引入mongoose
const mongoose = require('mongoose');

//2.链接mongodb数据库 connect 连接
mongoose.connect('mongodb://127.0.0.1:27017/project');

//3.设置连接的回调
mongoose.connection.on('open',()=>{

 //4.声明文档结构
 const PhoneSchema = new mongoose.Schema({
 brand:String,
 color:String,
 price:Number,
 tags:Array
 })
 
 //5.创建模型对象
 const PhoneModel = mongoose.model('phone',PhoneSchema);
 
 PhoneModel.insertMany([
 {
 brand:'华为',
 color:'灰色',
 price:2399,
 tags:['电量大','屏幕大','信号好']
 },
 {
 brand:'小米',
 color:'白色',
 price:2099,
 tags:['电量大','屏幕大','信号好']
 }
 ],(err,data)=>{
 if(err) throw err;
 console.log('写入成功');
 mongoose.connection.close();
 })
})

删除
删除一条数据

SongModel.deleteOne({_id:'5dd65f32be6401035cb5b1ed'}, function(err){
 if(err) throw err;
 console.log('删除成功');
 mongoose.connection.close();
});

批量删除

SongModel.deleteMany({author:'Jay'}, function(err){
 if(err) throw err;
 console.log('删除成功');
 mongoose.connection.close();
});

更新
更新一条数据

SongModel.updateOne({author: 'JJ Lin'}, {author: '林俊杰'}, function (err) {
 if(err) throw err;
 mongoose.connection.close();
});

批量更新数据

SongModel.updateMany({author: 'Leehom Wang'}, {author: '王力宏'}, function (err) {
 if(err) throw err;
 mongoose.connection.close();
});

查询
查询一条数据

SongModel.findOne({author: '王力宏'}, function(err, data){
 if(err) throw err;
 console.log(data);
 mongoose.connection.close();
});

//根据 id 查询数据
SongModel.findById('5dd662b5381fc316b44ce167',function(err, data){
 if(err) throw err;
 console.log(data);
 mongoose.connection.close();
});

批量查询数据

//不加条件查询
SongModel.find(function(err, data){
 if(err) throw err;
 console.log(data);
 mongoose.connection.close();
});

//加条件查询
SongModel.find({author: '王力宏'}, function(err, data){
 if(err) throw err;
 console.log(data);
 mongoose.connection.close();
});

5.3.7条件控制

运算符
在 mongodb 不能 > < >= <= !== 等运算符,需要使用替代符号
· > 使用 $gt
· < 使用 $lt
· >= 使用 $gte
· <= 使用 $lte
· !== 使用 $ne

db.students.find({id:{$gt:3}}); id号比3大的所有的记录

5.3.8逻辑运算

逻辑或 $or

db.students.find({$or:[{age:18},{age:24}]});

逻辑与 $and

db.students.find({$and: [{age: {$lt:20}}, {age: {$gt: 15}}]});

正则匹配
条件中可以直接使用 JS 的正则语法,通过正则可以进行模糊查询

db.students.find({name:/imissyou/});

5.3.9个性化读取

字段筛选

//0:不要的字段
//1:要的字段

SongModel.find().select({_id:0,title:1}).exec(function(err,data){
 if(err) throw err;
 console.log(data);
 mongoose.connection.close();
});

数据排序

//sort 排序
//1:升序
//-1:倒序

SongModel.find().sort({hot:1}).exec(function(err,data){
 if(err) throw err;
 console.log(data);
 mongoose.connection.close();
});

数据截取

//skip(n) 跳过n条数据 limit(n)限定几条数据

SongModel.find().skip(10).limit(10).exec(function(err,data){
 if(err) throw err;
 console.log(data);
 mongoose.connection.close();
});
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值