上一篇介绍了如何建立项目、路由的访问以及如何建立模块,这篇来说讲数据库的链接与使用。前端
既然是后端项目,固然要能连上数据库,不然还不如直接写静态页面。mysql
本教程使用的是 MySQL,有人可能会问为啥不用 MongoDB。。。呃,由于公司使用 MySQL,我也是结合项目经历写的教程,MongoDB 还没踩过坑,因此就不在这误人子弟了。git
首先要确保你有数据库能够链接,若是没有,能够在 MySQL 官网下载一个,本地跑起来。安装教程这里就不叙述了,“百度一下,你就知道”。github
推荐使用 Navicat Premium 可视化工具来管理数据库。sql
用 Navicat 链接上数据库后,新建一个库:typescript
点开咱们刚建立的库 nest_zero_to_one
,点开 Tables,发现里面空空如也,接下来咱们建立一张新表,点开上面工具栏的 Query,并新增查询:数据库
将下列代码复制到框内,点击上面的运行,便可完成表的建立:npm
CREATE TABLE `admin_user` (
`user_id` smallint(6) NOT NULL AUTO_INCREMENT COMMENT '用户ID',
`account_name` varchar(24) NOT NULL COMMENT '用户帐号',
`real_name` varchar(20) NOT NULL COMMENT '真实姓名',
`passwd` char(32) NOT NULL COMMENT '密码',
`passwd_salt` char(6) NOT NULL COMMENT '密码盐',
`mobile` varchar(15) NOT NULL DEFAULT '0' COMMENT '手机号码',
`role` tinyint(4) NOT NULL DEFAULT '3' COMMENT '用户角色:0-超级管理员|1-管理员|2-开发&测试&运营|3-普通用户(只能查看)',
`user_status` tinyint(4) NOT NULL DEFAULT '0' COMMENT '状态:0-失效|1-有效|2-删除',
`create_by` smallint(6) NOT NULL COMMENT '建立人ID',
`create_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '建立时间',
`update_by` smallint(6) NOT NULL DEFAULT '0' COMMENT '修改人ID',
`update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '修改时间',
PRIMARY KEY (`user_id`),
KEY `idx_m` (`mobile`)
) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8 COMMENT='后台用户表';
复制代码
而后咱们能够看到,左边的 Tables
下多出了 admin_user
表,点开就能够看到字段信息了:后端
咱们先随便插入2条数据,方便后面的查询:数组
先在项目根目录建立一个文件夹 config
(与 src
同级),专门放置各类配置。
而后新建一个文件 db.ts
:
// config/db.ts
const productConfig = {
mysql: {
port: '数据库端口',
host: '数据库地址',
user: '用户名',
password: '密码',
database: 'nest_zero_to_one', // 库名
connectionLimit: 10, // 链接限制
},
};
const localConfig = {
mysql: {
port: '数据库端口',
host: '数据库地址',
user: '用户名',
password: '密码',
database: 'nest_zero_to_one', // 库名
connectionLimit: 10, // 链接限制
},
};
// 本地运行是没有 process.env.NODE_ENV 的,借此来区分[开发环境]和[生产环境]
const config = process.env.NODE_ENV ? productConfig : localConfig;
export default config;
复制代码
Ps:这个文件是不一样步到 github 的,须要各位读者结合实际状况配置
市面上有不少链接数据库的工具,笔者这里使用的是 Sequelize
,先安装依赖包:
$ npm i sequelize sequelize-typescript mysql2 -S
或
$ yarn add sequelize sequelize-typescript mysql2 -S
复制代码
而后在 src
目录下建立文件夹 database
,而后再建立 sequelize.ts
:
// src/database/sequelize.ts
import { Sequelize } from 'sequelize-typescript';
import db from '../../config/db';
const sequelize = new Sequelize(db.mysql.database, db.mysql.user, db.mysql.password || null, {
// 自定义主机; 默认值: localhost
host: db.mysql.host, // 数据库地址
// 自定义端口; 默认值: 3306
port: db.mysql.port,
dialect: 'mysql',
pool: {
max: db.mysql.connectionLimit, // 链接池中最大链接数量
min: 0, // 链接池中最小链接数量
acquire: 30000,
idle: 10000, // 若是一个线程 10 秒钟内没有被使用过的话,那么就释放线程
},
timezone: '+08:00', // 东八时区
});
// 测试数据库连接
sequelize
.authenticate()
.then(() => {
console.log('数据库链接成功');
})
.catch((err: any) => {
// 数据库链接失败时打印输出
console.error(err);
throw err;
});
export default sequelize;
复制代码
好了,接下来咱们来测试一下数据库的链接状况。
咱们重写 user.service.ts
的逻辑:
// src/logical/user/user.service.ts
import { Injectable } from '@nestjs/common';
import * as Sequelize from 'sequelize'; // 引入 Sequelize 库
import sequelize from '../../database/sequelize'; // 引入 Sequelize 实例
@Injectable()
export class UserService {
async findOne(username: string): Promise<any | undefined> {
const sql = ` SELECT user_id id, real_name realName, role FROM admin_user WHERE account_name = '${username}' `; // 一段平淡无奇的 SQL 查询语句
try {
const res = await sequelize.query(sql, {
type: Sequelize.QueryTypes.SELECT, // 查询方式
raw: true, // 是否使用数组组装的方式展现结果
logging: true, // 是否将 SQL 语句打印到控制台,默认为 true
});
const user = res[0]; // 查出来的结果是一个数组,咱们只取第一个。
if (user) {
return {
code: 200, // 返回状态码,可自定义
data: {
user,
},
msg: 'Success',
};
} else {
return {
code: 600,
msg: '查无此人',
};
}
} catch (error) {
return {
code: 503,
msg: `Service error: ${error}`,
};
}
}
}
复制代码
保存文件,就会看到控制台刷新了(前提是使用 yarn start:dev
启动的),并打印下列语句:
这说明以前的配置生效了,咱们试着用以前的参数请求一下接口:
返回“查无此人”,说明数据库没有叫“Kid”的用户。
咱们改为正确的已存在的用户名再试试:
而后观察一下控制台,咱们的查询语句已经打印出来了,经过 logging: true
,能够在调试 Bug 的时候,更清晰的查找 SQL 语句的错误,不过建议测试稳定后,上线前关闭,否则记录的日志会很繁杂:
再对照一下数据库里的表,发现查出来的数据和数据库里的一致,至此,MySQL 链接测试完成,之后就能够愉快的在 Service 里面搬砖了。
这篇介绍了 MySQL 的数据准备、Sequelize 的配置、Nest 怎么经过 Sequelize 链接上 MySQL,以及用一条简单的查询语句去验证链接状况。
在这里,强烈建议使用写原生 SQL 语句去操做数据库。
虽然 Sequelize 提供了不少便捷的方法,具体可去 Sequelize v5 官方文档 浏览学习。但笔者经过观察 logging
打印出来的语句发现,其实多了不少无谓的操做,在高并发的状况下,太影响性能了。
并且若是不使用原生查询,那么就要创建对象映射到数据库表,而后每次工具更新,还要花时间成本去学习,若是数据库改了字段,那么映射关系就会出错,而后项目就会疯狂报错以至宕机(亲身经历)。
而使用原生 SQL,只须要学一种语言就够了,换个工具,也能用,并且就算改了字段,也只会在请求接口的时候报错,到时候再针对那个语句修改就行了,并且如今查找替换功能这么强大,批量修改也不是难事。
最重要的是,若是你是从前端转后端,或者根本就是0基础到后端,仍是建议先把 SQL 的基础打牢,否则连 JOIN
、LEFT JOIN
和 RIGHT JOIN
的区别都分不清(咱们公司就有个三年经验的后端,乱用 LEFT JOIN
,而后被 DB 主管一顿痛骂。。。真事儿)。
多写、多分析、多看控制台报错、多从性能上考虑,才是最快入门的途径。
注意:在写 UPDATE 更新语句的时候,必定要加上 WHERE 条件,必定要加上 WHERE 条件,必定要加上 WHERE 条件,重要的事情说3遍,血与泪的教训!!!
下一篇,将介绍如何使用 JWT(Json Web Token)进行单点登陆。
`