MongoDB 是一个基于分布式文件存储的数据库,官方地址 https://www.mongodb.com/
数据库(DataBase)是按照数据结构来组织、存储和管理数据的 应用程序
数据库的主要作用就是 管理数据 ,对数据进行 增(c)、删(d)、改(u)、查(r)
相比于纯文件管理数据,数据库管理数据有如下特点:
操作语法与JavaScript类似,容易上手,学习成本低
Mongodb 中有三个重要概念需要掌握
{
"accounts": [
{
"id": "3-YLju5f3",
"title": "买电脑",
"time": "2023-02-08",
"type": "-1",
"account": "5500",
"remarks": "为了上网课"
},
{
"id": "3-YLju5f4",
"title": "请女朋友吃饭",
"time": "2023-02-08",
"type": "-1",
"account": "214",
"remarks": "情人节聚餐"
},
{
"id": "mRQiD4s3K",
"title": "发工资",
"time": "2023-02-19",
"type": "1",
"account": "4396",
"remarks": "终于发工资啦!~~"
}
],
"users": [
{
"id": 1,
"name": "zhangsan",
"age": 18
},
{
"id": 2,
"name": "lisi",
"age": 20
},
{
"id": 3,
"name": "wangwu",
"age": 22
}
]
}
下载地址: **https://www.mongodb.com/try/download/community **
建议选择 zip 类型, 通用性更强
配置步骤如下:
1> 将压缩包移动到 C:\Program Files 下,然后解压
2> 创建 C:\data\db 目录,mongodb 会将数据默认保存在这个文件夹
3> 以 mongodb 中 bin 目录作为工作目录,启动命令行
4> 运行命令 mongod
看到最后的 waiting for connections 则表明服务 已经启动成功
然后可以使用 mongo 命令连接本机的 mongodb 服务
注意:
为了方便后续方便使用 mongod 命令,可以将 bin 目录配置到环境变量 Path 中
千万不要选中服务端窗口的内容 ,选中会停止服务,可以 敲回车 取消选中
命令行交互一般是学习数据库的第一步,不过这些命令在后续用的比较少,所以大家了解即可
show dbs
use 数据库名
db
use 库名
db.dropDatabase( )
db.createCollection(‘集合名称’)
show collections
db.集合名.drop( )
db.集合名.renameCollection(‘newName’)
db.集合名.insert(文档对象);
db.集合名.find(查询条件)
_id 是 mongodb 自动生成的唯一编号,用来唯一标识文档
db.集合名.update(查询条件,新的文档)
db.集合名.update({name:‘张三’},{$set:{age:19}})
db.集合名.remove(查询条件)
Mongoose 是一个对象文档模型库,官网 http://www.mongoosejs.net/
//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: String,
author: String,
price: Number
});
//6. 创建文档模型对象
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('连接关闭');
})
类型 | 描述 |
---|---|
String | 字符串 |
Number | 数字 |
Boolean | 布尔值 |
Array | 数组,也可以使用[ ]来标识 |
Date | 日期 |
Buffer | Buffer对象 |
Mixed | 任意类型,需要使用 mongoose.Schema.Types.Mixed 指定 |
ObjectId | 对象ID,需要使用 mongoose.Schema.Types.ObjectId 指定 |
Decimal128 | 高精度数字,需要使用 mongoose.Schema.Types.Decimal128 指定 |
Mongoose 有一些内建验证器,可以对字段值进行验证
title: {
type: String,
required: true // 设置必填项
},
author: {
type: String,
default: '匿名' // 默认值
},
gender: {
type: String,
enum: ['男','女'] // 设置的值必须是数组中的
},
username: {
type: String,
unique: true
},
unique需要 重建集合 才能有效果
永远不要信息用户的输入
数据库的基本操作包括四个,增加(create),删除(delete),修改(update),查(read)
插入一条
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
})
//6.创建模型对象
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();
});
在 mongodb 不能 > < >= <= !== 等运算符,需要使用替代符号
使用 $gt
= 使用 $gte
//id号比3大的所有的记录
db.studentsfind({ id: { $gt: 3 } }, (err, data) => {
if (err) {
console.log('提取失败!');
return;
}
console.log(data);
})
$or 逻辑或的情况
db.studentsfind({ $or: [{ age: 18 }, { age: 24 }] }, (err, data) => {
if (err) {
console.log('提取失败!');
return;
}
console.log(data);
})
$and 逻辑与的情况
db.studentsfind({ $and: [{ age: { $lt: 20 } }, { age: { $gt: 15 } }] }, (err, data) => {
if (err) {
console.log('提取失败!');
return;
}
console.log(data);
})
条件中可以直接使用 JS 的正则语法,通过正则可以进行模糊查询
db.studentsfind({ name: /imissyou/ }, (err, data) => {
if (err) {
console.log('提取失败!');
return;
}
console.log(data);
})
或者写为
db.studentsfind({ name: new RegExp('imissyou') }, (err, data) => {
if (err) {
console.log('提取失败!');
return;
}
console.log(data);
})
//0:不要的字段
//1:要的字段
BookModel.find().select({name:1,author:1}).exec((err,data)=>{
if(err){
console.log('查询失败!');
return;
}
console.log(data);
})
//只返回每个字段的 name 和 author
//sort 排序
//1: 升序
//-1:倒序
BookModel.find().sort({ hot: 1 }).exec((err, data) => {
if (err) {
console.log('查询失败!');
return;
}
console.log(data);
})
//只返回每个字段的 name 和 author
//skip 跳过
//limit 限定
BookModel.find().skip(10).limit(10).exec((err, data) => {
if (err) {
console.log('查询失败!');
return;
}
console.log(data);
})
我们可以使用图形化的管理工具来对 Mongodb 进行交互,这里演示两个图形化工具
接口是 前后端通信的桥梁
简单理解:一个接口就是 服务中的一个路由规则,根据请求响应结果
接口的英文单词是 API(Application Program Interface),所以有时也称之为API接口
一个接口一般由如下几个部分组成
RESTful API 是一种特殊风格的接口,主要特点有如下几个:
规则实例:
操作 | 请求类型 | URL | 返回 |
---|---|---|---|
新增歌曲 | POST | /song | 返回新生成的歌曲信息 |
删除歌曲 | DELETE | /song/10 | 返回一个空文档 |
修改歌曲 | PUT | /song/10 | 返回更新后的歌曲信息 |
修改歌曲 | PATCH | /song/10 | 返回更新后的歌曲信息 |
获取所有歌曲 | GET | /song | 返回歌曲列表数组 |
获取单个歌曲 | GET | /song/10 | 返回单个歌曲信息 |
json-server本身是一个JS编写的工具包,可以快速搭建RESTful API服务
操作步骤:
npm i -g json-server
{
"song": [
{ "id": 1, "name": "干杯", "singer": "五月天" },
{ "id": 2, "name": "当", "singer": "动力火车" },
{ "id": 3, "name": "不能说的秘密", "singer": "周杰伦" }
]
}
json-server --watch db.json
默认监听端口为3000
介绍几个接口测试工具
所谓会话控制就是 对会话进行控制
HTTP 是一种无状态的协议,它没有办法区分多次的请求是否来自于同一个客户端, 无法区分用户
而产品中又大量存在的这样的需求,所以我们需要通过 会话控制 来解决该问题
常见的会话控制技术有三种:
cookie 是 HTTP 服务器发送到用户浏览器并保存在本地的一小块数据
cookie 是保存在浏览器端的一小块数据
cookie 是按照域名划分保存的
例子:
域名 | cookie |
---|---|
www.baidu.com | a=100;b=200 |
www.bilibili.com | xid=1020abce121; hm=112411213 |
jd.com | x=100;ocw=12414cce |
浏览器向服务器发送请求时,会自动将 当前域名下 可用的 cookie 设置在请求头中,然后传递给服务器
这个请求头的名字也叫 cookie ,所以将 cookie 理解为一个 HTTP 的请求头也是可以的
填写账号和密码校验身份,校验通过后再发cookie
有了cookie之后,后续向服务器发送请求时,就会自动携带cookie
浏览器操作cookie的操作,使用相对较少
express中可以使用 cookie-parser 进行处理
const express = require('express');
//1. 安装 cookie-parser npm i cookie-parser
//2. 引入 cookieParser 包
const cookieParser = require('cookie-parser');
const app = express();
//3. 设置 cookieParser 中间件
app.use(cookieParser());
//4-1 设置 cookie
app.get('/set-cookie', (request, response) => {
// 不带时效性
response.cookie('username', 'wangwu');
// 带时效性
response.cookie('email', '[email protected]', { maxAge: 5 * 60 * 1000 });
//响应
response.send('Cookie的设置');
});
//4-2 读取 cookie
app.get('/get-cookie', (request, response) => {
//读取 cookie
console.log(request.cookies);
//响应体
response.send('Cookie的读取');
});
//4-3 删除cookie
app.get('/delete-cookie', (request, response) => {
//删除
response.clearCookie('username');
//响应
response.send('cookie 的清除');
});
//4. 启动服务
app.listen(3000, () => {
console.log('服务已经启动....');
});
不同浏览器中的cookie是相互独立的,不共享
session是保存在 服务器端的一块儿数据,保存当前访问用户的相关信息
实现会话控制,可以识别用户的身份,快速获取当前用户的相关信息
填写账号和密码校验身份,校验通过后创建 session信息,然后将session_id 的值通过响应头返回给浏览器
有了cookie,下次发送请求时就会自动携带cookie,服务器通过cookie中的session_id的值确定用户的身份
express中可以使用 express-session 对session进行操作
const express = require('express');
//1. 安装包 npm i express-session connect-mongo
//2. 引入 express-session connect-mongo
const session = require("express-session");
const MongoStore = require('connect-mongo');
const app = express();
//3. 设置 session 的中间件
app.use(session({
name: 'sid', //设置cookie的name,默认值是:connect.sid
secret: 'atguigu', //参与加密的字符串(又称签名)
saveUninitialized: false, //是否为每次请求都设置一个cookie用来存储session的id
resave: true, //是否在每次请求时重新保存session
store: MongoStore.create({
mongoUrl: 'mongodb://127.0.0.1:27017/project' //数据库的连接配置
}),
cookie: {
httpOnly: true, // 开启后前端无法通过 JS 操作
maxAge: 1000 * 300 // 这一条 是控制 sessionID 的过期时间的!!!
},
}))
//创建 session
app.get('/login', (req, res) => {
//设置session
req.session.username = 'zhangsan';
req.session.email = '[email protected]'
res.send('登录成功');
})
//获取 session
app.get('/home', (req, res) => {
console.log('session的信息');
console.log(req.session.username);
if (req.session.username) {
res.send(`你好 ${req.session.username}`);
} else {
res.send('登录 注册');
}
})
//销毁 session
app.get('/logout', (req, res) => {
//销毁session
// res.send('设置session');
req.session.destroy(() => {
res.send('成功退出');
});
});
app.listen(3000, () => {
console.log('服务已经启动, 端口 ' + 3000 + ' 监听中...');
});
cookie 和 session 的区别主要有如下几点:
token 是服务端生成并返回给 HTTP 客户端的一串加密字符串, token 中保存着 用户信息
实现会话控制,可以识别用户的身份,主要用于移动端 APP
填写账号和密码校验身份,校验通过后响应token,token一般是在响应体中返回给客户端
后续发送请求时,需要手动将token添加到请求报文中,一般是放在请求头中
JWT(JSON Web Token )是目前最流行的跨域认证解决方案,可用于基于 token 的身份验证
JWT 使 token 的生成与校验更规范
我们可以使用 jsonwebtoken 包 来操作 token
//导入 jsonwebtokan
const jwt = require('jsonwebtoken');
//创建 token
// jwt.sign(数据, 加密字符串, 配置对象)
let token = jwt.sign({
username: 'zhangsan'
}, 'atguigu', {
expiresIn: 60 //单位是 秒
})
//解析 token
jwt.verify(token, 'atguigu', (err, data) => {
if (err) {
console.log('校验失败~~');
return
}
console.log(data);
})