前端与移动开发----Node.js----操作MySQL数据库

Node.js

回顾

express中间件: 可以在请求到达服务器后, 先经过中间件函数的处理, 然后再转交给路由进行业务逻辑的运行

中间件 - 就是一个函数, 而且所有的中间件都共享同一个req和res对象

中间件分为:

  • 全局中间件: 在路由以上 - 任何请求过来从上到下被中间件处理 - 注意一定要最后执行next()才能往下运行

    app.use(函数体) // 在路由以上使用
    app.get()
    app.post()
    
  • 局部中间件: 在某个路由命中后, 才执行的中间件叫局部中间件, 只对这个路由生效

    app.get("/api/list", (req, res, next) => {
        next();
    })
    
  • 错误中间件: 一般写在整个项目路由的最后, 而且参数有4个, 需要上一级next()传递下来信息才可以出发

    app.use((err, req, res, next) => {
        
    })
    
  • 内置中间件:

    • express.static(“静态资源文件夹”) - 原地返回一个函数, 用于解析用户要请求的静态资源, 从指定的文件夹下寻找, 如果找到直接返回, 找不到就匹配下一个中间件, 直到报错返回
    • express.urlencoded() - 用于解析前端请求体里的参数, 并绑定到req的body属性上使用
  • 自定义中间件

    • 可以在全局 / 局部自己定义函数
    • 可以自己定义函数, 封装在模块暴露出来, 引入使用
  • 第三方中间件

    • 别人自定义的中间件, 拿过来一个函数, 集成到自己的express项目中
    • multer, express-jwt
  • 路由器中间件

    const express = require("express");
    const router = express.Router();
    
    router.get()
    

跨域问题解决:

  • 简单请求
    • GET / POST / HEAD
    • 请求头只能有Content-Type等
  • 非简单请求
    • PUT / DELETE
    • Content-Type的值是application/json
    • 简单请求对立面的

16. 数据库介绍

以前数据保存在变量上, 或者保存在浏览器本地, 现在我们知道数据真正在哪里了

什么是数据库

数据库 (database) 是用来组织、存储和管理数据的仓库

为什么学数据库

当今世界是一个充满着数据的互联网世界,充斥着大量的数据。数据的来源有很多,比如出行记录、消费记录、浏览的商品、发送的消息等等。除了文本类型的数据,图像、音乐、声音都是数据(存储的是文件的地址)

为了方便管理互联网世界中的数据,就有了数据库管理系统的概念(简称:数据库)。用户可以对数据库中的数 据进行新增、查询、更新、删除等操作

  • 增删改查
    • 新增
    • 查询
    • 修改
    • 删除

前端与移动开发----Node.js----操作MySQL数据库_第1张图片

学完数据库能干什么

​ 我们可以设计数据存放的结构, 进行有序和结构化的管理, 方便我们进行查找和使用. 现在的大数据和所有你用的网站以及应用都离不开数据库在后面默默的支持.

​ 听没听说过, 删库跑路, 可见数据库的重要性.

常见的数据库及分类

市面上的数据库有很多种,最常见的数据库有如下几个:

  • MySQL 数据库(目前使用最广泛、流行度最高的的开源免费数据库;)
  • Oracle 数据库(收费)
  • SQL Server 数据库(收费)
  • Mongodb 数据库(Community + Enterprise)

其中,MySQL、Oracle、SQL Server 属于传统型数据库(又叫做:关系型数据库 或 SQL 数据库),这三者的 设计理念相同,用法比较类似。

而 Mongodb 属于新型数据库(又叫做:非关系型数据库 或 NoSQL 数据库),它在一定程度上弥补了传统型 数据库的缺陷。

17. MySQL简介

MySQL是一个关系型数据库管理系统,由瑞典MySQL AB 公司开发,目前属于 Oracle 旗下产品

我们常说数据库,其实只是一个泛指。那么数据库的结构是怎样的呢?

  • 数据库服务器
    • 数据库(一般来说,一个项目,都会使用一个独立的数据库)
      • 数据表(真正存储数据的地方)
        • 行与列(每一行代表一条数据。列又叫做字段)

前端与移动开发----Node.js----操作MySQL数据库_第2张图片

真正存储数据的是数据表。数据表和我们见过的Excel表格结构基本相同。

数据表的结构和excel一模一样。

id(不允许重复) name age sex tel
1 小明 23 13200008888
2 小传 23 13300008888
3 小黑 25 18866669999
4 老智 32 13200008888

安装MySQL

MySQL 服务器软件(phpStudy) ---- 存储数据,可以创建数据库、数据表 - 下载地址: https://www.xp.cn/

安装Navicat软件

MySQL图形化管理工具(Navicat) — 可以使用它管理(创建、增删改查等等)数据库

启动MySQL

phpStudy软件打开后, 启动MySQL服务 - 电脑就可以提供数据库服务了, 就像node xxx.js 启动web服务

前端与移动开发----Node.js----操作MySQL数据库_第3张图片

Navicat使用

一定要确保mysql启动了, 才能让navicat链接这个数据库服务, 操作这个电脑里的数据库里的东西

连接到MySQL服务器

打开 Navicat软件。

前端与移动开发----Node.js----操作MySQL数据库_第4张图片

前端与移动开发----Node.js----操作MySQL数据库_第5张图片

创建 - 数据库

前端与移动开发----Node.js----操作MySQL数据库_第6张图片

前端与移动开发----Node.js----操作MySQL数据库_第7张图片

创建 - 表

比如创建一个学生信息表:

id(不允许重复) name age sex tel
1 小明 23 13200008888
2 小传 23 13300008888
3 小黑 25 18866669999
4 老智 32 13200008888

对于一张表,最重要的是表头的设计

对于数据库中的数据表,最重要的设计也是表头,只不过在数据库中把表头叫做字段

下面是关于id的设计:

前端与移动开发----Node.js----操作MySQL数据库_第8张图片

下面是完整的创建表:

前端与移动开发----Node.js----操作MySQL数据库_第9张图片

名(表头) 类型 长度 不是null 其他
id int 勾选自动递增
name varchar 20
age int
sex varchar 2
  • id – 自动递增 – √

  • 最后保存,填表名 student

  • 其他补充点

    • 数据库中的数字类型
      • tinyint -128~127
      • smallint -65535 ~ 65535
      • int -21亿 ~ 21亿
      • bigint 更大
    • 数据库中的字符串类型
      • varchar - 变长字符串类型
      • char - 定长字符串类型
      • text - 很长的字符(65535)
      • longtext - 21亿个字符

    前端与移动开发----Node.js----操作MySQL数据库_第10张图片

18. SQL语句(重点)

SQL(英文全称:Structured Query Language)是结构化查询语言,专门用来访问和处理数据库的编程语言。

三个关键点

  1. SQL 是一门数据库编程语言
  2. 使用 SQL 语言编写出来的代码,叫做 SQL 语句
  3. SQL 语言只能在关系型数据库(例如 MySQL、Oracle、SQL Server)中使用。非关系型数据库(例如 Mongodb) 不支持 SQL 语言

SQL能做什么

  • 从数据库中查询数据
  • 向数据库中插入新的数据
  • 更新数据库中的数据
  • 从数据库删除数据
  • 可以创建新数据库
  • 可在数据库中创建新表
  • 无所不能

打开navicat的执行SQL语句的功能

前端与移动开发----Node.js----操作MySQL数据库_第11张图片

18.0 添加数据 - sql语句

基本的格式: insert into 表名 …

方式一:指定字段和值,只要字段和值对应即可。和顺序无关

格式: insert into 表名 (字段, 字段, ...) values (,, ...)

例如:
insert into student (name, age, sex) values ('虚空恐惧', 98, '男')

方式二:和顺序有关,因为没指定字段,所以值必须是所有的值,而且顺序和表中字段的顺序要一致

格式: insert into 表名 values (,, ...)

例如: 
insert into student values (null, '光辉女郎', 28, '女', 13900202020)

方式三使用set里设置新数据的值,没有顺序关系

格式: insert into 表名 set 字段=, 字段=, ....

例如: 
insert into student set age=30, sex='男', name='李青', tel=13900409202

18.1 查询数据 - sql语句

语法格式:

  • SQL语句,不区分大小写。
-- 查询某几个字段带值
SELECT 字段1, 字段2,... FROM 表名
select 字段1, 字段2,... from 表名

例如:
select id, name FROM student

-- 查询所有的字段带值
SELECT * FROM 表名

例如:
select * from stduent

-- 带条件的查询
SELECT * FROM 表名 WHERE 条件 ORDER BY 排序字段 LIMIT 开始位置下标, 长度

例如:
select * from student where age > 18 ORDER BY age LIMIT 0, 2

18.2 练习

练习1: 查询所有学生的姓名和年龄

SELECT id,name FROM student;

练习2: 查询全部学生的全部信息

SELECT * FROM student;

18.3 带where子句的查询

select field1, field2… from 表名 查询表中的所有数据

where 可以使用条件来筛选查询出的结果

前端与移动开发----Node.js----操作MySQL数据库_第12张图片

-- 查询年龄小于20的学生
-- select * from student where 条件
-- select * from student where age < 20

-- 查询age大于18的女学生
-- select * from student where age > 18 and sex = '女'

-- 查询年龄大于等于20小于等于30的学生
-- select * from student where age>=20 and age<=30
-- select * from student where age between 20 and 30

18.4 模糊查询

通配符:

  • %: 代表任意长度(包括0)的任意字符

  • _: 代表1位长度的任意字符

like: 在执行模糊查询时,必须使用like来作为匹配条件

-- 带where条件的查询 -- 模糊查询(某个字段, 包含关键字)
-- 语法: select * from 表名 where 字段 like '%关键字%'

-- 查询名字中带有李的
-- select * from student where username like '%李%'

-- 查询名字的最后一个字是祥的
-- select * from student where username like '%祥'

18.5 统计查询

  • max 查询最大值 select max(age) from student
  • Min 查询最小值 select min(age) from student
  • avg 查询平均值 select avg(age) from student
  • sum 查询总和(查询所有学生的年龄之和) select sum(age) from student
  • count 查询总记录数(查询共计有多少个学生) select count(*) cc from student
-- 统计查询(最大值、最小值、平均值、总和、总记录数)

-- 查询最大的年龄
-- select max(age) from student

-- 查询最小的年龄
-- select min(age) from student

-- 查询年龄的平均值
-- select avg(age) from student

-- 查询年龄的总和(所有人的年龄加到一起)
-- select sum(age) from student

-- 重点:查询总记录数(一共有多少条数据)
-- select count(*) from student

-- 可以为查询到的字段定义别名
-- select id,username from student
-- select id as abc, username as hello from student
-- select id abc, username hello from student
select count(*) total from student

18.6 查询结果排序

order by 可以对查询结果按某个字段进行升序或者降序排列

  • 升序 asc (默认值)
  • 降序 desc

可进行排序的字段通常是 整型 英文字符串型 日期型 (中文字符串也行,但一般不用)

-- 对查询结果进行排序
-- 语法:select * from student order by 字段 [asc/desc]
-- asc 默认就是 asc,表示升序(从小到大排序)
-- desc ,表示降序(从大到小排序)

-- 查询所有的学生,并按年龄升序排序
-- select * from student order by age
-- select * from student order by age asc

-- 查询所有的学生,按年龄降序排序
-- select * from student order by age desc


-- 查询所有的男同学,并按年龄降序排序
-- sql中,既有条件,又有排序,条件要写到前面,排序要写到后面
-- 条件是条件、排序是排序,之间没有任何关系,中间不要加and、or之类的
select * from student where sex='男' order by age desc

注意:如果SQL语句中,有where和order by,where一定要放到order by之前

18.7 限制查询结果

limit 用来限制查询结果的起始点和长度

  • 格式: limit start, length
    • start: 起始点。 查询结果的索引,从0开始。 0代表第一条数据。如果省略start,则默认表示从0
    • length: 长度
-- 限制查询结果(类似于截取查询结果)
-- 语法:select * from student limit 起始位置, 长度
-- 起始位置:从0开始,0表示第1条数据的位置。如果从0的位置截取,0可以省略
-- 长度:表示长度的数字

-- 查询所有学生中的第1、2、3个
-- select * from student limit 0, 3
-- select * from student limit 3

-- 查询所有学生中的第4、5、6个
-- select * from student limit 3, 3

-- 如果SQL中,有条件、有排序、有limit。那么顺序应该是
-- 先写条件、再写排序、最后写limit,并且每一部分之间用空格隔开即可
-- 查询年龄最大的学生的全部信息(id、name、age、sex)
-- select * from student order by age desc limit 1

-- 查询年龄最小的女同学的信息
select * from stu where sex='女' order by age asc limit 1

注意:where、order by、limit如果一起使用,是有顺序的,where在最前面、其次是order by、limit要放到最后。另外三者之间没有and之类的

小结

  • 控制查询的列数
    • select 字段, 字段, … from student ---- 选择查询指定的列
    • select * from student ---- 查询所有的列
  • 控制查询的行数
    • where 条件
      • where id>3
      • where id>3 and age<30
      • where id<3 or sex=‘男’
      • where name like ‘%斯%’
    • order by 字段 排序规则
      • order by age asc
      • order by age desc
    • limit 起始位置, 长度
      • limit 0, 3 相当于 limit 3
      • limit 3, 3

select 字段 from 表名 [where 条件] [order by 排序字段 排序规则] [limit 起始位置,长度]

select count(*) as total from 表名 – 查询总记录数

18.8 修改数据 - sql语句

格式:

update 表名 set 字段1=值1, 字段2=值2,... where 修改条件

修改表中的哪一条(几条)数据的 字段1=值1…

不指定修改条件会修改所有的数据

update student set age=20, sex='女' where id=11

update student set age=25, sex='女'

18.9 删除数据 - sql语句

格式: delete from 表名 where 删除条件

注意:不指定条件将删除所有数据

-- 删除一条数据
delete from student where id=11

-- 删除满足条件的数据
delete from student where id>6

-- 没有指定条件,删除全部数据
delete from student

drop table stu; – 删除stu表

drop database 111_db – 删除库

小结

  • 添加
    • insert into 表名 set 字段=值, 字段=值, 字段=值, …
  • 更新
    • update 表名 set 字段=值, 字段=值, 字段=值 where 条件
  • 删除
    • delete from 表名 where 条件

18.10 导入导出

  • 导入
    • 数据库名上面 --> 右键 --> 运行SQL文件 --> 选择SQL文件,运行即可完成导入。
    • 导入注意事项,表名不能重复,如果重复会发生覆盖。
  • 导出
    • 在数据库名字上,比如 student 上,右键 --> 转储SQL文件 --> 结构和数据,选择保存位置保存即可

18.11 多表联合查询

查询班级号为2的学生信息

SELECT s.name, s.age, s.id, s.class_id FROM student s JOIN classes c ON s.class_id = c.id WHERE c.id = 2

19. node中的mysql模块

刚才是直接使用sql语句, 去操作数据库, 但是前端发起请求只能到达node层面的js代码, 所以应该让node编写代码, 链接mysql数据库, 并且执行预先编写好的mysql语句执行, 操作数据库

前端 <-> nodejs(express+mysql模块) <-> 数据库

19.0 mysql模块的作用 - 以及占位符

mysql模块是一个第三方模块,专门用来操作MySQL数据库。 可以执行增删改查操作

# 如果前面没有安装过其他模块,需要先初始化npm init
npm i mysql

小故事

curd: 就代表数据库的增删改查

c: create 就是添加 (增)

u: update 就是修改 (改)

r: read 就是查询 (查)

d: delete 就是删除 (删)

在js代码中, mysql模块使用

  1. 加载 MySQL 模块

  2. 创建 MySQL 连接对象

  3. 连接 MySQL 服务器

  4. 执行SQL语句

  5. 关闭链接

// 1. 加载mysql模块
const mysql = require('mysql');
// 2. 创建连接对象(设置连接参数)
const conn = mysql.createConnection({
    // 属性:值
    host: 'localhost',
    port: 3306,
    user: 'root',
    password: '',
    database: 'yingxiong'
});

// 3. 连接到MySQL服务器
conn.connect();

// 4. 完成查询(增删改查)
/*
conn.query(SQL语句, [SQL中占位符的值], (err, result, fields) => {
    err: 错误信息
    result: 查询结果
    fields: 当前查询过程中涉及到的字段信息,一般用不着
});
*/

// 5. 关闭连接,释放资源
conn.end();

19.1 新增 - 数据

// 执行sql语句
// let sql = `INSERT INTO student SET name='小可爱', age=18, sex='女', tel=13900202121`;
// conn.query(sql, (err, result, fields) => {
//     if (err) console.log(err);
//     else {
//         console.log(result);
//         console.log(fields);
//     }
// });

// 带占位符的写法
// (1): 用?占个位置, 在真正执行的时候, 会被替换为具体的值
let sql = `INSERT INTO student SET name=?, age=?, sex=?, tel=?`;
// (2): 参数2数组里的每个值按照顺序, 替换到?对应的位置上
conn.query(sql, ['娜娜', 20, '女', 13900004000], (err, result, fields) => {
    if (err) console.log(err);
    else {
        console.log(result);
        console.log(fields);
    }
});
// 插入的快捷方式
let userObj = {
    name: "小米",
    age: 20,
    sex: "男",
    tel: 13900203123
}
let sql = `INSERT INTO student SET ?`;
conn.query(sql, userObj, (err, results, fields) => {
    if (err) console.log(err);
    else {
        console.log(results);
        console.log(fields);
    }
})

19.2 查询 - 数据

// 查询数据
// let sql = `SELECT * FROM student WHERE age > 18 ORDER BY id LIMIT 0, 2`;
// conn.query(sql,  (err, result, fields) => {
//     if (err) console.log(err);
//     else {
//         console.log(result);
//     }
// });
// 带占位符
let sql = `SELECT * FROM student WHERE age > ? ORDER BY id LIMIT ?, ?`;
conn.query(sql, [18, 0, 2], (err, result, fields) => {
    if (err) console.log(err);
    else {
        console.log(result);
    }
});

19.3 修改 - 数据

// 修改数据
// let sql = `UPDATE student SET name='哈哈', age=10, sex='男', tel=12300201302 WHERE id = 1`;
// conn.query(sql,  (err, result, fields) => {
//     if (err) console.log(err);
//     else {
//         console.log(result);
//     }
// });

// 带占位符
let sql = `UPDATE student SET name=?, age=?, sex=?, tel=? WHERE id = ?`;
conn.query(sql, ['改后名字', 18, '男', 19020203030, 1], (err, result, fields) => {
    if (err) console.log(err);
    else {
        console.log(result);
    }
});

// 快捷更新方式
let obj = {
    name: "改后的名字",
    age: 18,
    sex: "男",
    tel: 13900201010,
    id: 1
}

let sql = `UPDATE student SET ? WHERE id = ?`;
conn.query(sql, [obj, obj.id], (err, result, fields) => {
    if (err) console.log(err);
    else {
        if (result.affectedRows > 0) { // 改变的条数大于0, 证明有数据被修改了
            console.log("数据修改成功");
        } else {
            console.log("修改失败-可能数据不存在");
        }
    }
});

强调

对于增删改语句,返回的result是一个表示SQL执行结果的对象。其主要属性如下:

  • insertId 添加时有该属性,表示新增数据的id
  • affectedRows 受影响行数,表示受影响的行数。增删改的时候都有该属性
  • changRows 改变的行数,修改操作的时候,会有该属性

19.4 删除 - 数据

// 删除数据
// let sql = `DELETE FROM student WHERE id = 7`;
// conn.query(sql,  (err, result, fields) => {
//     if (err) console.log(err);
//     else {
//         console.log(result);
//     }
// });

// 带占位符
let sql = `DELETE FROM student WHERE id = ?`;
conn.query(sql, [6], (err, result, fields) => {
    if (err) console.log(err);
    else {
        if (result.affectedRows > 0) {
            console.log("删除成功");
        } else {
            console.log("删除失败, 可能数据不存在");
        }
    }
});

基本的增删改查小结

  • 查询语句
    • result – 数组
    • 数组的每个单元,就是查询到的一行数据
  • 添加语句
    • result – 对象
    • result.affectedRows – 受影响的行数
    • result.insertId – 新增数据id
  • 修改语句
    • result – 对象
    • result.affectedRows – 受影响的行数(满足条件的)
    • result.changedRows – 被改变的行数
  • 删除语句
    • result – 对象
    • result.affectedRows – 受影响的行数

19.5 标记删除

物理删除 - 使用delete的SQL语句, 会真正从表里(磁盘上)抹去这个数据 - 无法找回, 但是如果不小心用户删除了, 想要找回, 怎么办呢?

逻辑删除(也叫标记删除) - 就是用一个字段, 来表示这一条数据的状态, 字段名字随便起, 例如叫status, 0代表无效, 1代表还存在.

给数据表student, 再添加一个字段, 叫status, 控制学生是否还存在

// 标记占位符, 就是把那条数据的status改成0, 以后查询时, 只查数据为1的
// let sql = `UPDATE student SET ? WHERE id = ?`;
// conn.query(sql, [{status: 0}, 9], (err, result, fields) => {
//     if (err) console.log(err);
//     else {
//         if (result.affectedRows > 0) {
//             console.log("删除成功");
//         } else {
//             console.log("删除失败, 可能数据不存在");
//         }
//     }
// });

// 注释掉上面代码, 我们查询下所有 有效的数据
let sql = `SELECT * FROM student WHERE sex = ? and status = ?`;
conn.query(sql, ['男', 1], (err, result, fields) => {
    if (err) console.log(err);
    else {
        console.log(result);
    }
});

20 封装MySQL

  • 封装mysql,然后导出
function theMySQL(sql, params, callback) {
    const mysql = require('mysql');
    const conn = mysql.createConnection({
        host: 'localhost',
        user: 'root',
        password: 'root',
        database: '121_db'
    });
    conn.connect();

    // 完成增删改查
    conn.query(sql, params, callback);

    conn.end();
}

// 导出
module.exports = theMySQL;

如有不足,请多指教,
未完待续,持续更新!
大家一起进步!

你可能感兴趣的:(前端与移动开发学习笔记,node.js,mysql,node.js,前端)