likes
comments
collection
share

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

作者站长头像
站长
· 阅读数 49

前言

选用Koa作为web框架,用三篇文章讲解Node.js编写接口、服务端渲染(SSR)和MySQL数据库

前两篇已经讲了接口和服务端渲染,接下来学习后端最重要的内容 —— 数据库

预备知识

本篇的基础是您熟悉了第一篇的内容

🌰举几个栗子,用Koa两天入门Node.js后端开发(一) | 接口篇

🚩学习目标

用Koa + Mysql实现4个接口,数据保存到数据中

  1. 新增用户(POST请求)
  2. 查询用户信息(GET请求)
  3. 修改用户密码(GET请求)
  4. 删除用户(GET请求)

1. 什么是数据库?

“按照数据结构来组织、储存和管理数据的仓库”

🌰简单举个栗子

  • 注册账号需要数据库存储信息

  • 登录账号需要读取数据库信息

  • 修改密码需要修改数据库信息

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

数据库有4个主要操作【增、删、改、查】

  • 增:在数据库中 新增 一条/多条数据
  • 删: …… 删除 ……
  • 改: …… 修改 ……
  • 查: …… 查询 ……

举几个常用的数据库

数据库费用模型下载地址
MySQL社区版免费关系型数据库downloads.mysql.com/archives/in…
Oracle收费关系型数据库
SQL Server收费关系型数据库
MongoDB社区版免费非关系数据库www.mongodb.com/try/downloa…
Redis社区版免费非关系数据库redis.io/download
Access收费关系型数据库

数据库模型主要有两种:关系型数据库和非关系型数据库

关系型(SQL)和非关系型(NOSQL)数据库的区别?

二者区别非常多,详细的区别请自行百度

🌰举个不恰当的栗子

关系型 :数据储存成表格形式,就像上面的表格一样,有行和列

非关系型 :数据储存的是信息组合,比如对象键值对

本文以MySQL为例,结合Koa讲解后端的接口和数据库使用

2. 准备工作

🚧MySQL 8.0

没有安装MySQL?🤔

👉 MySQL 8.0 下载地址

安装步骤参考以下掘友的文章,我就不重复写了

环境安装——MySQL安装

windows详细安装mysql步骤

💥 一定记好设置的密码!

💥 一定记好设置的密码!

在cmd命令窗口中使用命令查看是否安装完成

mysql -V

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

输出MySQL的版本就表示安装完成

登录到MySQL

mysql -u root -p

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

如图所示结果就链接成功

确认MySQL运行没问题,关掉命令行。后面使用软件操作,不使用命令行

🚦 启动报错

ERROR 2003 (HY000): Can't connect to MySQL server on 'localhost:3306' (10061)

解决:检查MySQL的服务是否启动

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

🚧MySQL 管理工具

推荐使用 Navicat PreMium 15 免费试用14天

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

  1. 运行Navicat,新建连接

    🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

  2. 填写链接信息

    连接名:随便写

    主机:localhost

    端口:3306

    用户名:root

    密码:安装时设置的密码

    💡 左下角【测试连接】按钮点击,弹出“连接成功”表示连接没问题

    🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

  3. 展开连接就能看到MySQL的一些系统数据库,后面将新建一个自己的库

    🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

  4. 执行SQL语句

    • 在数据上右击 --> 新建查询

    • 弹出的查询窗口中输入SQL语句

    • 点击运行按钮

    💡 创建数据库可以在本地上右击或使用可视化窗口

    🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

💥执行SQL后记得【右击 - 刷新】

  1. 编辑数据

    编辑表格里的数据,需要点击下方的【对号】提交更改,否则不会生效

    🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

🚧Node.js

Node.js 版本 >= 10

需要安装Koa-generatorKoa

如果您不了解Koa,建议先看这篇文章

🌰举几个栗子,用Koa两天入门Node.js后端开发(一)

🚧请求工具

我用Hoppscotch(原名postwoman)你也可以用其他请求工具,postman,apifox,apipost等

👉 GitHub

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

3. 一些知识

开始写代码之前,先了解一些数据库的知识和概念。

😜简单且通俗

3.1 字段和纪录

MySQL以表的形式存储数据,表中的行叫做纪录,表中的列叫做字段

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

🌰举个栗子

在Excel中,通常说年龄,在数据库中叫做年龄字段

在Excel中,通常说张三这一,在数据库中叫做张三这条纪录

一个数据库中可以有多个表,表和表之间能通过字段建立关联

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

🌰举个栗子

表a表b通过各自的字段1 建立了关联。有了关联就能联查数据,比如查询下表中张三的年龄和性别,就需要关联年龄表性别表

年龄表

姓名年龄
张三18

性别表

姓名性别
张三

💥注意:

实际开发中不要使用中文表名和字段名

3.2 主键

完整名称是“主键约束” (PRIMARY KEY),一般情况每张表都会设置一个主键。

💡目的是确保该条纪录的唯一性,表和表之间建立关联需要主键

  • 每个表只能定义一个主键
  • 主键不能重复且不能为NULL
  • 两个字段联合可以作为一个主键

🌰举个栗子

将2.1表中的姓名作为年龄表的主键,姓名作为性别表的主键。两表可以使用姓名建立关联

实际开发中因为重名的问题,姓名是不能作为主键的

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

3.3 数据类型

数据库中同样有数据类型和长度,通常在创建表时指定字段类型和字段长度

几个常用的数据类型

类型大小格式用途
int4 Bytes大整数值
float4 Bytes单精度浮点数值
double8 Bytes双精度浮点数值
varchar0-65535 bytes变长字符串
blob0-65 535 bytes二进制形式的长文本数据
date3 BytesYYYY-MM-DD日期值
datetime8 BytesYYYY-MM-DD HH:MM:SS混合日期和时间值
timestamp4 BytesYYYYMMDD HHMMSS时间戳

详细的取值范围去菜鸟教程里看吧 👉 MySQL 数据类型

🌰 举个栗子

# 定义3位的整型变量age
age int(3)

# 定义20位的字段串name
name varchar(20)

💡 注意:int(M)中的长度M与你存放的数值型的数的大小无关

详细解释

3.4 SQL写法

通过前面的知识,知道SQL语句操作的是 表、字段、纪录(ps:当然还有其他的,但不是本文的内容😜)

增删改查四个方面看SQL语句的写法,简单拆分SQL语句,由3部分组成

  1. 动作(新建表,修改表,查看表....)
  2. 操作的表(表名,字段...)
  3. 条件(where...)

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

以下语句在Navicat中可依次执行查看效果

3.4.1 增

  • 新建数据库 - 名称:example

    CREATE DATABASE example;
    
  • 新建表 - 名称:people,包括字段name,age(name是主键)

    CREATE TABLE people(name varchar(25) PRIMARY KEY, age int(3));
    
  • 增加字段 - 在people表中增加sex字段

    ALTER TABLE people ADD sex varchar(2);
    
  • 增加一条纪录 - 在people表中增加“张三,18,男”

    insert into people (name, age, sex) values('张三', 18, '男');
    

💡 SQL语句中的关键字不区分大小写

3.4.2 改

  • 修改表名 - 修改people表名为person

    ALTER TABLE people RENAME TO person;
    
  • 修改字段 - 在person表中修改age字段为years,类型不变

    ALTER TABLE person CHANGE age years int(3);
    
  • 修改字段 - 在person表中修改years字段类型长度为2

    ALTER TABLE person MODIFY years int(3);
    

    💡 修改字段名用CHANGE,修改数据类型用MODIFY。

    😁详细区别自行百度

  • 修改纪录 - 修改person表中“张三”的年龄为20

    UPDATE person SET years=20 WHERE name='张三'
    

    修改多个字段值用逗号,隔开years=20, sex='女'

3.4.3 查

  • 查询纪录(全部结果) - 查询person表中所有数据

    SELECT * FROM person
    
  • 查询纪录(部分字段) - 查询person表中name是“张三”的年龄

    SELECT years FROM person WHERE name='张三'
    
  • 查询纪录 - 查询person表中name是“张三”,sex是“男”的数据

    SELECT * FROM person WHERE name='张三' AND sex='男'
    
  • 查询纪录 - 多表联查

    # 现在只有person一张表,需要扩充一下
    # 新建 mail 表(name是主键)
    CREATE TABLE mail(name varchar(25) PRIMARY KEY, msg varchar(200));
    
    # 插入一条数据
    INSERT INTO mail (name, msg) values('张三', '请周末来加班!');
    
    # 联查 所有人的年龄和信息
    SELECT person.name, person.years, mail.msg FROM person, mail WHERE person.name = mail.name
    

    联查有多种方法,比如 inner join left join right join

    😁详细用法自行百度

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

3.4.4 删

  • 删除字段 - 删除person表中sex字段

    ALTER TABLE person DROP COLUMN sex;
    
  • 删除纪录 - 删除person中里名为“张三”的纪录

    DELETE FROM person WHERE name='张三';
    
  • 删除表 - 删除person表

    DROP TABLE person;
    
  • 删除数据库

    DROP DATABASE example;
    

MySQL知识非常多,各种语句要多练习。了解简单的写法以后,我们来看在Node.js中怎样写SQL语句。

4. Node.js中使用MySQL

🌰举几个栗子,用Koa两天入门Node.js后端开发(一)中学习了Koa怎样写接口,继续在之前的项目中写本篇的代码

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

用Koa+MySQL实现增删改查4个功能

  1. 增加用户
  2. 查询用户信息
  3. 修改用户信息
  4. 删除用户

4.1 连接数据库

首先,新建一个数据库koadb

CREATE DATABASE koadb;

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

安装MySQL的npm包mysql2

为什么是mysql2?

npm主页 🤡更快,更高,更强

npm i mysql2

在项目的根目录创建数据的连接文件pool.js

const mysql = require('mysql2')

// 注意修改成你的连接信息
const config = {
  database: 'koadb',  // 数据库
  username: 'root',   // 用户
  password: '000000', // 密码
  port: '3306',       // MySQL端口号
  host: 'localhost'   // MySQL地址
}

const pool = mysql.createPool(config)

module.exports = conn

注意修改config中的连接信息,conn就创建了一个数据连接

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

4.2 调用SQL

首先引用pool.js,然后参考下面的写法

无参数SQL

const [rows, fields] = await pool.query('SELECT * FROM USER')

传参SQL

const [rows, fields] = await pool.query('SELECT * FROM USER WHERE NAME = ?',['张三'])

预先生成SQL

const sql = pool.format('SELECT * FROM USER WHERE NAME = ?',['张三'])
const [rows, fields] = await pool.query(sql)

错误处理

const sql = pool.format('SELECT * FROM USER WHERE NAME = ?',['张三'])
pool.query(sql,(err, rows, fields)=>{
    //...
})

4.3 设计数据表

根据4个功能,共设计2张数据表,一张用户表,一张密码表

user - 用户表

字段数据类型长度含义
idint5主键
namevarchar32用户名
levelint1等级

pwd - 密码表

字段数据类型长度含义
idint5主键
namevarchar32用户名
passwordvarchar18密码

两表通过id 字段关联

4.4 创建数据表

新建 user - 用户表

CREATE TABLE USER (
	id INT ( 5 ) PRIMARY KEY,
name VARCHAR ( 32 ),
level INT ( 1 ));

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

双击表名,查看一下创建完成的表,确认没有问题

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

新建pwd - 密码表

CREATE TABLE PWD (
	id INT ( 5 ) PRIMARY KEY,
name VARCHAR ( 32 ),
password VARCHAR ( 18 ));

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

双击表名,查看一下创建完成的表,确认没有问题

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

4.5 事务

写代码前还需要了解最后一个概念事务

事务是应用程序中一系列严密的操作,所有操作必须成功完成,否则在每个操作中所作的所有更改都会被撤消。

🌰 举个栗子

新增用户需要在userpwd两表中各添加一条数据,使用事务以后,要么两条都插入成功,要么两条都失败。

不会出现一条成功,一条失败,这样保证了数据的一致性

// 省略...
//开启事务
const conn = await pool.getConnection()
await conn.beginTransaction()
try {
    // ...
    // MySQL操作
    // ...
    await conn.commit() //提交事务
    conn.release() //释放连接
} catch (e) {
    console.log(e)
    conn.rollback() //回滚事务
}

5. 接口

有了数据库连接以后,创建4个接口。

  • 新增用户 - /sql/addUser
  • 查询信息 - /sql/getUser
  • 修改密码 - /sql/changUserPassword
  • 删除用户 - /sql/deleteUser

根据🌰举几个栗子,用Koa两天入门Node.js后端开发(一)学习的内容,新建sql.js

引用之前新建的query.js

const router = require('koa-router')()
const pool = require('../pool')

router.prefix('/sql')

module.exports = router

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

app.js中添加调用

// ……省略
const sql = require('./routes/sql')
// ……省略
app.use(sql.routes(), sql.allowedMethods())

💡 写接口之前,需要先写出SQL语句,然后根据SQL语句再定义接口参数

5.1 新增用户(POST)

📢 在sql.js中新增addUser接口,用于创建新用户。这个接口也是4个接口中最复杂的接口。

每个用户到两张表 userpwd 来存储level和password

新建用户的SQL语句

# 在用户表插入一条
INSERT INTO USER ( id, name, level )
VALUES
	( '1', 'Maokai', 0 );

# 在密码表插入一条
INSERT INTO PWD ( id, name, password )
VALUES
	( '1', '张三', '123456$' );

从SQL看出一共需要传4个值 idnamelevelpassword ,其中id需要自动生成,其他值由传参拿到。

请求参数:

{
    name:'',
    password:'',
    level:''
}

📘 id生成逻辑: 取user表里当前最大的id,新id在此基础上加1,用SQL语句表示。(也可以在建表时设置自增id)

SELECT 
	COALESCE( max( id ), 0 ) + 1 id
FROM USER

✨接口代码

/*
 * 新增用户
 */
router.post('/addUser', async (ctx, next) => {
  const { name, password, level } = ctx.request.body
  try {
    if (!(name && password && level)) {
      throw '缺少参数'
    }
    // 获取新id
    const idSQL = 'SELECT	COALESCE( max( id ), 0 ) + 1 id FROM USER'
    const [[{ id }]] = await pool.query(idSQL)
    // 获取MySQL连接
    const conn = await pool.getConnection()
    await conn.beginTransaction()

    const userSQL = pool.format('INSERT INTO USER ( id, name, level ) VALUES( ?, ?, ? )', [id, name, level])
    const pwdSQL = pool.format('INSERT INTO PWD ( id, name, password ) VALUES( ?, ?, ? )', [id, name, password])

    await conn.query(userSQL)
    await conn.query(pwdSQL)
    // 提交事务
    await conn.commit()
    // 释放MySQL连接
    conn.release()
    ctx.body = `增加用户成功,id:${id},name:${name}`
  } catch (e) {
    conn.rollback()
    ctx.body = e
  }
})

使用Hoppscotch 测试接口(POST)

http://localhost:3000/sql/addUser

请求参数

{
  "name": "MaoKai",
  "password": "123456$",
  "level": 1
}

可以看到正确返回了nameid

图片比较大,耐心等待👇

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

5.2 查询信息(GET)

📢 在sql.js中新增getUser接口,查询用户信息。

每个用户信息存到两张表中 userpwd ,但是查询接口仅需user

查询信息的SQL语句

SELECT
	* 
FROM USER 
WHERE
	id = 1

从SQL看出只需要传1个值 id

使用Koa的路由参数:/getUser/1

✨接口代码

/*
 * 查询信息
 */
router.get('/getUser/:id', async (ctx, next) => {
  const { id } = ctx.params
  try {
    if (!id) {
      throw '缺少参数'
    }
    const userSQL = pool.format('SELECT * FROM USER WHERE ID = ?', [id])
    const [rows] = await pool.query(userSQL)
    const { name, level } = rows[0]
    ctx.body = `用户信息:\n id:${id}\n name:${name}\n level:${level}`
  } catch (e) {
    ctx.body = e
  }
})

使用Hoppscotch 测试接口(POST)

http://localhost:3000/sql/getUser/1

可以看到正确返回了用户信息

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

5.3 修改密码(POST)

📢 在sql.js中新增changPassword接口,用于修改密码。逻辑是先校验旧密码,如果正确则修改,错误则返回

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

修改密码只需要pwd

修改密码的SQL语句

# 查询旧密码
SELECT password 
FROM	pwd 
WHERE
	id = 1

# 修改成新密码
UPDATE pwd 
SET password = '123'
WHERE
	id = 1

从SQL看出一共需要传3个值 idpasswordnewPassword

请求参数:

{
    id:'',
    newPassword:'',
    password:''
}

✨接口代码

/*
 * 修改密码
 */
router.post('/changPassword', async (ctx, next) => {
  const { id, password, newPassword } = ctx.request.body
  try {
    if (!(id && password && newPassword)) {
      throw '缺少参数'
    }
    const pwdSQL = pool.format('SELECT password current FROM PWD WHERE ID = ?', [id])
    const [[{ current }]] = await pool.query(pwdSQL)

    if (password !== current) {
      throw '密码错误,请检查'
    }

    const newPwdSQL = pool.format('UPDATE pwd SET password = ? WHERE ID = ?', [newPassword, id])
    await pool.query(newPwdSQL)

    ctx.body = `id:${id} 密码修改成功, 新密码:${newPassword}`
  } catch (e) {
    ctx.body = e
  }
})

使用Hoppscotch 测试接口(POST)

http://localhost:3000/sql/changPassword

请求参数

{
  "id": 1,
  "password": "123456$",
  "newPassword": "@@@"
}

可以看到数据库中的pasword字段被更新了

图片比较大,耐心等待👇

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

5.4 删除用户(GET)

📢 在sql.js中新增deleteUser接口,删除用户。

每个用户信息存到两张表中 userpwd ,删除用户时需要同时删除。

删除的SQL语句,这次用一个连接语句

DELETE
	user,pwd 
FROM
	user,pwd 
WHERE
	user.id = pwd.id
	AND user.id = '1'

从SQL看出只需要传1个值 id

使用Koa的路由参数:/deleteUser/1

✨接口代码

/*
 * 删除用户
 */
router.get('/deleteUser/:id', async (ctx, next) => {
  const { id } = ctx.params
  try {
    if (!id) {
      throw '缺少参数'
    }
    const userSQL = pool.format('SELECT * FROM USER WHERE ID = ?', [id])
    const [rows] = await pool.query(userSQL)
    const { name, level } = rows[0]
    ctx.body = `用户信息:\n id:${id}\n name:${name}\n level:${level}`
  } catch (e) {
    ctx.body = e
  }
})

使用Hoppscotch 测试接口(POST)

http://localhost:3000/sql/getUser/1

可以看到删除了用户(注意:即使用户不存在也不会报错)

🌰举几个栗子,用Koa两天入门Node.js后端开发(三)

最后

到这里,Koa后端快速入门就结束了,3篇文章简单写了一些Koa的知识,掘友们在这方面也有诸多优秀文章,还要大家自己去发现。

😜万水千山总是情,点个关注行不行~

转载自:https://juejin.cn/post/7067887882458890253
评论
请登录