飞翔的鱼 飞翔的鱼
首页
  • Http
  • Ajax
  • Node
  • MongoDB
  • Axios
  • Git
  • Webpack
  • React
  • Vue
  • Uni-app
  • 性能优化
  • 移动端
  • HTML
  • CSS
  • stylus
  • 常用
  • 实战
  • 实用网站
  • 资源库
  • Vue专区
关于
  • css效果
  • js效果
  • 拥抱生活
  • 生活知道
GitHub (opens new window)

Wang

飞翔的鱼
首页
  • Http
  • Ajax
  • Node
  • MongoDB
  • Axios
  • Git
  • Webpack
  • React
  • Vue
  • Uni-app
  • 性能优化
  • 移动端
  • HTML
  • CSS
  • stylus
  • 常用
  • 实战
  • 实用网站
  • 资源库
  • Vue专区
关于
  • css效果
  • js效果
  • 拥抱生活
  • 生活知道
GitHub (opens new window)
  • Http

  • Ajax

  • Node

  • MongoDB

    • mongodb
      • 基本命令
      • 在Node中如何操作MongoDB数据库
        • 使用官方的MongoDB包来操作
        • 使用第三方包mongoose来操作(推荐使用)
      • 回调函数
      • Promise
      • 修改完代码自动重启
      • 封装异步API
      • 数组的遍历方法,都是对函数作为一种参数
      • EcmaScript 6
      • 目录结构
      • 模板页
      • 路由设计
      • 模型设计
      • 功能实现
      • 步骤
      • 中间件的概念
      • 中间件的分类:
        • 应用程序级别的中间件
        • 路由级别的中间件
        • 总
      • 错误处理中间件
      • 内置中间件
      • 第三方中间件
  • Axios

  • Git

  • Webpack

  • React

  • Vue

  • Uni-app

  • 性能优化

  • 移动端

  • 前端
  • MongoDB
wang jiaqi
2021-03-17

mongodb

# MongoDB

# 基本命令

show dbs		//查看数据库列表(数据库中的所有数据库)
1
db				    //查看当前连接的数据库
1
use 数据库名称	     //切换到指定的数据库,(如果没有会新建)
1
show collections 	//查看当前目录下的所有集合(数据表)
1
db.集合名.find()	  //查看表中的详细信息
1

# 在Node中如何操作MongoDB数据库

# 使用官方的MongoDB包来操作

http://mongodb.github.io/node-mongodb-native/
1

# 使用第三方包mongoose来操作(推荐使用)

https://mongoosejs.com/    //官网
1

第一步安装mongoose:(在哪里使用安装在哪里)

npm i mongoose --save
1

第二步连接数据库 (此案例数据库名为demo)

//连接数据库
//引入mongoose
let mongoose = require('mongoose')
mongoose.set('useCreateIndex',true) //使用一个新的索引创建器
//1.连接数据库
mongoose.connect('mongodb://localhost:27017/demo',{
    useNewUrlParser: true, //使用一个新的URL解析器,用于解决一些安全性问题。
    useUnifiedTopology: true //使用一个统一的新的拓扑结构
})
//2.绑定数据库连接的监听
mongoose.connection.on('open',function (err) {
    if(err){
        console.log('数据库连接失败',err)
    }else {
        console.log('数据库连接成功')
        //3.操作数据库
        //3.1. ------ 引入模式对象
        let Schema = mongoose.Schema

        //3.2.--------  创建约束对象
        let studentsRule = new Schema({
            stu_id: {
                type: String, //限制学号必须为:字符串
                required: true,
                unique: true
            },
            name: {
                type: String, //限制姓名必须为:字符串
                required: true, //限制姓名为必填项
            },
            age: {
                type: Number, //限制年龄必须为:字符串
                required: true, //限制年龄为必填项
            },
            sex: {
                type: String, //限制性别必须为:字符串
                required: true, //限制性别为必填项
            },
            hobby: [String], //限制爱好只能为数组,数组中的每一项必须为字符串
            info: Schema.Types.Mixed, //接收所有类型
            date: {
                type: Date,
                default: Date.now()
            },
            enable_flag: {
                type: String,
                default: 'Y'
            }
        })

    //3.3.------- 创建模型对象('students'是自己创建的集合)
    let stuModel = mongoose.model('students',studentsRule) //用于生成某个集合所对应的模型对象
   	//4进行CURD操作	
  }
})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56

第三步:进行CURD操作(对应第二步里面的4)

-Create

   模型对象.create(文档对象,回调函数)
   模型对象.create(文档对象)
stuModel.create({
      stu_id:'004',
      name:'强',
      age:'42',
      sex:'男',
      hobby:['女','打代码','打篮球'], //限制爱好只能为数组,数组中的每一项必须为字符串
      info:'一个风一样的男子', //接收所有类型
    },function(err,data){
        if (!err) console.log(data)
        else console.log(err)
    })
1
2
3
4
5
6
7
8
9
10
11

-Read

   模型对象.find(查询条件[,投影])不管有没有数据,都返回一个数组
   模型对象.findOne(查询条件[,投影])找到了返回一个对象,没找到返回null
   find方法:
        1.返回的是一个数组,就算是一条数据,也包裹一个数组
        2.若查询结果为空,则返回一个空数组。
   findOne方法:
        1.若有结果,返回的是一个对象
        2.若没有结果,返回一个null
stuModel.find({name:'小明'},function (err,data) {
      if (!err) console.log(data)
      else console.log(err)
    })
stuModel.findOne({name:'班长',age:42},function (err,data) {
      if (!err) console.log(data)
      else console.log(err)
    })
1
2
3
4
5
6
7
8

-Update

  模型对象.updateOne(查询条件,要更新的内容[,配置对象])
  模型对象.updateMany(查询条件,要更新的内容[,配置对象])
  备注:存在update方法,但是即将废弃,查询条件匹配到多个时,依然只修改一个,强烈建议用updateOne或updateMany
stuModel.updateOne({name:'静静'},{age:16},function (err,data) {
      if (!err) console.log(data)
      else console.log(err)
    })
1
2
3
4

-Delete

   模型对象.deleteOne(查询条件)
   模型对象.deleteMany(查询条件)
   备注:没有delete方法,会报错!
stuModel.deleteMany({age:16},function (err,data) {
      if (!err) console.log(data)
      else console.log(err)
    })
1
2
3
4

备注: 以上所有方法,如果没有指定回调函数,则返回值是一个Promise对象

# 使用Node操作MySQL数据库

文档:https://www.npmjs.com/package/mysql

安装:

npm install --save  mysql
1
// 引入mysql包
var mysql      = require('mysql');

// 创建连接
var connection = mysql.createConnection({
  host     : 'localhost',	//本机
  user     : 'me',		//账号root
  password : 'secret',	//密码12345
  database : 'my_db'	//数据库名
});
 
// 连接数据库	(打开冰箱门)
connection.connect();
 
//执行数据操作	(把大象放到冰箱)
connection.query('SELECT * FROM `users` ', function (error, results, fields) {
  if (error) throw error;//抛出异常阻止代码往下执行
  // 没有异常打印输出结果
  console.log('The solution is: ',results);
});

//关闭连接	(关闭冰箱门)
connection.end();
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

# 异步编程

# 回调函数

不成立的情况下:

function add(x,y){
    console.log(1);
    setTimeout(function(){
        console.log(2);
        var ret = x + y;
        return ret;
    },1000);
    console.log(3);
    //到这里执行就结束了,不会i等到前面的定时器,所以直接返回了默认值 undefined
}

console.log(add(2,2));
// 结果是 1 3 undefined 4
1
2
3
4
5
6
7
8
9
10
11
12
13

使用回调函数解决:

回调函数:通过一个函数,获取函数内部的操作。(根据输入得到输出结果)

var ret;
function add(x,y,callback){
    // callback就是回调函数
    // var x = 10;
    // var y = 20;
    // var callback = function(ret){console.log(ret);}
    console.log(1);
    setTimeout(function(){
        var ret = x + y;
        callback(ret);
    },1000);
    console.log(3);
}
add(10,20,function(ret){
    console.log(ret);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
image-20200313084746701

注意:

​ 凡是需要得到一个函数内部异步操作的结果(setTimeout,readFile,writeFile,ajax,readdir)

​ 这种情况必须通过 回调函数 (异步API都会伴随着一个回调函数)

ajax:

基于原生XMLHttpRequest封装get方法:

var oReq = new XMLHttpRequest();
// 当请求加载成功要调用指定的函数
oReq.onload = function(){
    console.log(oReq.responseText);
}
oReq.open("GET", "请求路径",true);
oReq.send();
1
2
3
4
5
6
7
function get(url,callback){
    var oReq = new XMLHttpRequest();
    // 当请求加载成功要调用指定的函数
    oReq.onload = function(){
        //console.log(oReq.responseText);
        callback(oReq.responseText);
    }
    oReq.open("GET", url,true);
    oReq.send();
}
get('data.json',function(data){
    console.log(data);
});
1
2
3
4
5
6
7
8
9
10
11
12
13

# Promise

callback hell(回调地狱):

image-20200314143410972

文件的读取无法判断执行顺序(文件的执行顺序是依据文件的大小来决定的)(异步api无法保证文件的执行顺序)

var fs = require('fs');

fs.readFile('./data/a.text','utf8',function(err,data){
	if(err){
		// 1 读取失败直接打印输出读取失败
		return console.log('读取失败');
		// 2 抛出异常
		// 		阻止程序的执行
		// 		把错误信息打印到控制台
		throw err;
	}
	console.log(data);
});

fs.readFile('./data/b.text','utf8',function(err,data){
	if(err){
		// 1 读取失败直接打印输出读取失败
		return console.log('读取失败');
		// 2 抛出异常
		// 		阻止程序的执行
		// 		把错误信息打印到控制台
		throw err;
	}
	console.log(data);
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

通过回调嵌套的方式来保证顺序:

var fs = require('fs');

fs.readFile('./data/a.text','utf8',function(err,data){
	if(err){
		// 1 读取失败直接打印输出读取失败
		return console.log('读取失败');
		// 2 抛出异常
		// 		阻止程序的执行
		// 		把错误信息打印到控制台
		throw err;
	}
	console.log(data);
	fs.readFile('./data/b.text','utf8',function(err,data){
		if(err){
			// 1 读取失败直接打印输出读取失败
			return console.log('读取失败');
			// 2 抛出异常
			// 		阻止程序的执行
			// 		把错误信息打印到控制台
			throw err;
		}
		console.log(data);
		fs.readFile('./data/a.text','utf8',function(err,data){
			if(err){
				// 1 读取失败直接打印输出读取失败
				return console.log('读取失败');
				// 2 抛出异常
				// 		阻止程序的执行
				// 		把错误信息打印到控制台
				throw err;
			}
			console.log(data);
		});
	});
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

为了解决以上编码方式带来的问题(回调地狱嵌套),所以在EcmaScript6新增了一个API:Promise。

  • Promise:承诺,保证
  • Promise本身不是异步的,但往往都是内部封装一个异步任务

基本语法:

// 在EcmaScript 6中新增了一个API Promise
// Promise 是一个构造函数

var fs = require('fs');
// 1 创建Promise容器		resolve:解决   reject:失败
var p1 = new Promise(function(resolve, reject) {
	fs.readFile('./a.text', 'utf8', function(err, data) {
		if (err) {
			// console.log(err);
			// 把容器的Pending状态变为rejected
			reject(err);
		} else {
			// console.log(data);
			// 把容器的Pending状态变为resolve
			resolve(data);
		}
	});
});

// 当p1成功了,然后就(then)做指定的操作
// then方法接收的function就是容器中的resolve函数
p1
	.then(function(data) {
		console.log(data);
	}, function(err) {
		console.log('读取文件失败了', err);
	});

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28

!

链式循环:

封装Promise的readFile:

var fs = require('fs');

function pReadFile(filePath) {
	return new Promise(function(resolve, reject) {
		fs.readFile(filePath, 'utf8', function(err, data) {
			if (err) {
				reject(err);
			} else {
				resolve(data);
			}
		});
	});
}

pReadFile('./a.txt')
	.then(function(data) {
		console.log(data);
		return pReadFile('./b.txt');
	})
	.then(function(data) {
		console.log(data);
		return pReadFile('./a.txt');
	})
	.then(function(data) {
		console.log(data);
	})

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

mongoose所有的API都支持Promise:

// 查询所有
User.find()
	.then(function(data){
        console.log(data)
    })
1
2
3
4
5

注册:

User.findOne({username:'admin'},function(user){
    if(user){
        console.log('用户已存在')
    } else {
        new User({
             username:'aaa',
             password:'123',
             email:'fffff'
        }).save(function(){
            console.log('注册成功');
        })
    }
})
1
2
3
4
5
6
7
8
9
10
11
12
13
User.findOne({
    username:'admin'
})
    .then(function(user){
        if(user){
            // 用户已经存在不能注册
            console.log('用户已存在');
        }
        else{
            // 用户不存在可以注册
            return new User({
                username:'aaa',
                password:'123',
                email:'fffff'
            }).save();
        }
    })
    .then(funciton(ret){
		console.log('注册成功');
    })
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20

# 其他

# 修改完代码自动重启

我们在这里可以使用一个第三方命名行工具:nodemon来帮助我们解决频繁修改代码重启服务器的问题。

npm install -g nodemon		//安装nodemon
1

安装完毕之后使用:

nodemon app.js
1

# 封装异步API

回调函数:获取异步操作的结果

function fn(callback){
    // var callback = funtion(data){ console.log(data); }
	setTimeout(function(){
        var data = 'hello';
        callback(data);
    },1000);
}
// 如果需要获取一个函数中异步操作的结果,则必须通过回调函数的方式来获取
fn(function(data){
    console.log(data);
})
1
2
3
4
5
6
7
8
9
10
11

# 数组的遍历方法,都是对函数作为一种参数

# EcmaScript 6

参考文档:https://es6.ruanyifeng.com/

# 项目案例

# 目录结构

.
app.js	项目的入口文件
controllers
models	存储使用mongoose设计的数据模型
node_modules	第三方包
package.json	包描述文件
package-lock.json	第三方包版本锁定文件(npm5之后才有)
public	公共静态资源
routes
views	存储视图目录
1
2
3
4
5
6
7
8
9
10

# 模板页

  • 子模板
  • 模板继承

# 路由设计

路由 方法 get参数 post参数 是否需要登录 备注
/ get 渲染首页
/register(登录) get 渲染注册页面
/register post email,nickname,password 处理注册请求
/login get 渲染登陆界面
/login post email,password 处理登录请求
/loginout get 处理退出请求

# 模型设计

# 功能实现

# 步骤

  • 创建目录结构
  • 整合静态也-模板页
    • include
    • block
    • extend
  • 设计用户登陆,退出,注册的路由
  • 用户注册
    • 先处理客户端页面的内容(表单控件的name,收集表单数据,发起请求)
    • 服务端
      • 获取从客户端收到的数据
      • 操作数据库
        • 如果有错,发送500告诉客户端服务器错了‘
        • 其他的根据业务发送不同的响应数据
  • 登录
  • 退出

# Express中间件

# 中间件的概念

参考文档:http://expressjs.com/en/guide/using-middleware.html

中间件:把很复杂的事情分割成单个,然后依次有条理的执行。就是一个中间处理环节,有输入,有输出。

说的通俗易懂点儿,中间件就是一个(从请求到响应调用的方法)方法。

把数据从请求到响应分步骤来处理,每一个步骤都是一个中间处理环节。

var http = require('http');
var url = require('url');

var cookie = require('./expressPtoject/cookie');
var query = require('./expressPtoject/query');
var postBody = require('./expressPtoject/post-body');

var server = http.createServer(function(){
	// 解析请求地址中的get参数
	// var obj = url.parse(req.url,true);
	// req.query = obj.query;
	query(req,res);	//中间件
	
	// 解析请求地址中的post参数
	req.body = {
		foo:'bar'
	}
});

if(req.url === 'xxx'){
	// 处理请求
	...
}

server.listen(3000,function(){
	console.log('3000 runing...');
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

同一个请求对象所经过的中间件都是同一个请求对象和响应对象。

var express = require('express');
var app = express();
app.get('/abc',function(req,res,next){
	// 同一个请求的req和res是一样的,
	// 可以前面存储下面调用
	console.log('/abc');
	// req.foo = 'bar';
	req.body = {
		name:'xiaoxiao',
		age:18
	}
	next();
});
app.get('/abc',function(req,res,next){
	// console.log(req.foo);
	console.log(req.body);
	console.log('/abc');
});
app.listen(3000, function() {
	console.log('app is running at port 3000.');
});

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

image-20200317110520098

# 中间件的分类:

# 应用程序级别的中间件

万能匹配(不关心任何请求路径和请求方法的中间件):

app.use(function(req,res,next){
    console.log('Time',Date.now());
    next();
});
1
2
3
4

关心请求路径和请求方法的中间件:

app.use('/a',function(req,res,next){
    console.log('Time',Date.now());
    next();
});
1
2
3
4

# 路由级别的中间件

严格匹配请求路径和请求方法的中间件

get:

app.get('/',function(req,res){
	res.send('get');
});
1
2
3

post:

app.post('/a',function(req,res){
	res.send('post');
});
1
2
3

put:

app.put('/user',function(req,res){
	res.send('put');
});
1
2
3

delete:

app.delete('/delete',function(req,res){
	res.send('delete');
});
1
2
3

# 总

var express = require('express');
var app = express();

// 中间件:处理请求,本质就是个函数
// 在express中,对中间件有几种分类

// 1 不关心任何请求路径和请求方法的中间件
// 也就是说任何请求都会进入这个中间件
// 中间件本身是一个方法,该方法接收三个参数
// Request 请求对象
// Response 响应对象
// next 下一个中间件
// // 全局匹配中间件
// app.use(function(req, res, next) {
// 	console.log('1');
// 	// 当一个请求进入中间件后
// 	// 如果需要请求另外一个方法则需要使用next()方法
// 	next();
// 	// next是一个方法,用来调用下一个中间件
//  // 注意:next()方法调用下一个方法的时候,也会匹配(不是调用紧挨着的哪一个)
// });
// app.use(function(req, res, next) {
// 	console.log('2');
// });

// // 2 关心请求路径的中间件
// // 以/xxx开头的中间件
// app.use('/a',function(req, res, next) {
// 	console.log(req.url);
// });

// 3 严格匹配请求方法和请求路径的中间件
app.get('/',function(){
	console.log('/');
});
app.post('/a',function(){
	console.log('/a');
});

app.listen(3000, function() {
	console.log('app is running at port 3000.');
});

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43

# 错误处理中间件

app.use(function(err,req,res,next){
    console.error(err,stack);
    res.status(500).send('Something broke');
});
1
2
3
4

配置使用404中间件:

app.use(function(req,res){
    res.render('404.html');
});
1
2
3

配置全局错误处理中间件:

app.get('/a', function(req, res, next) {
	fs.readFile('.a/bc', funtion() {
		if (err) {
        	// 当调用next()传参后,则直接进入到全局错误处理中间件方法中
        	// 当发生全局错误的时候,我们可以调用next传递错误对象
        	// 然后被全局错误处理中间件匹配到并进行处理
			next(err);
		}
	})
});
//全局错误处理中间件
app.use(function(err,req,res,next){
    res.status(500).json({
        err_code:500,
        message:err.message
    });
});
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

# 内置中间件

  • express.static(提供静态文件)
    • http://expressjs.com/en/starter/static-files.html#serving-static-files-in-express

# 第三方中间件

参考文档:http://expressjs.com/en/resources/middleware.html

  • body-parser

  • compression

  • cookie-parser

  • mogran

  • response-time

  • server-static

  • session

    #

编辑 (opens new window)
#M#o#n#g#o#D#B# #-
上次更新: 2021/07/01, 20:33:02
node
测试

← node 测试→

最近更新
01
数组常用方法
05-21
02
边框
04-30
03
js1
04-29
更多文章>
Theme by Vdoing | Copyright © 2021-2021 本博客仅仅作为自己日常学习记录笔记使用
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×