-
Изучите синтаксис декоратора и почувствуйте его простоту и красоту; -
Изучите новую среду разработки самостоятельно, почувствуйте преимущества и недостатки различных платформ и заложите основу для будущей разработки и выбора; -
Почувствуйте сложность устранения неполадок на стороне сервера и найдите вдохновение для дизайна внешнего интерфейса.
-
https://www.geeksforgeeks.org/best-nodejs-frameworks-for-app-development/ -
https://anywhere.epam.com/business/best-node-js-frameworks
-
[Обязательно] База данных отсутствует, запрос интерфейса выполнен и его можно запускать; -
[Обязательно] Создайте базовую базу данных MySQL и получите доступ к библиотеке @nestjs/sequelize для выполнения функций добавления, удаления, изменения и запроса: CRUD -
[Необязательно] Мы планируем использовать Graphql для обработки запросов API для получения точных запросов данных. Это популярно уже давно, и в будущем мы планируем использовать его непосредственно в бизнесе. -
[Необязательно] Подключитесь к Swagger, чтобы автоматически генерировать документы API и быстро проводить совместную отладку и тестирование интерфейсных и серверных сервисов. Swagger — это инструмент с открытым исходным кодом для проектирования, создания, документирования и использования веб-сервисов RESTful. -
[Необязательно] Запрос интерфейса, обработка оптимизации базы данных
-
Разгрузка запросов, блокировка записи в базу данных и параллельная обработка процессов -
Добавьте промежуточное программное обеспечение для единообразной обработки запросов и ответов, выполнения обработки аутентификации, перехвата запросов и других операций. -
Разделенное резервное копирование базы данных, обработка аварийного восстановления базы данных, разделенная на: первичную, резервную, аварийную. -
Чтение и запись в базе данных разделены, данные записываются дважды, установлен механизм кэширования базы данных, для обработки используется redis.
# 进入文件夹目录
cd full-stack-demo/packages
# 安装脚手架
npm i -g @nestjs/cli
# 创建基础项目
nest new node-server-demo
# 进入项目
cd new node-server-demo
# 运行项目测试
npm run start:dev
-
common — класс общедоступного метода -
config — файл класса конфигурации -
контроллер — контроллер, используемый для обработки различных запросов, инициированных внешним интерфейсом -
service - класс сервиса, используемый для обработки логики взаимодействия с базой данных -
dto — DTO (объект передачи данных) можно использовать для проверки входных данных и ограничения передаваемых полей или форматов. -
сущности — класс сущностей, используемый для описания информации об атрибутах, связанных с объектом. -
модуль — модуль, используемый для регистрации всех классов обслуживания и классов контроллеров, аналогичный bean-компонентам в Spring.
Они не полностью эквивалентны. Два механизма реализации различны. Это просто, чтобы помочь всем понять.
main.ts — входная запись запуска
типы — типы объявлений, связанные с машинописным текстом
-
контроллерконтроллер
// packages/node-server-demo/src/controller/user/index.ts
import { Controller, Get, Query } from '@nestjs/common';
import UserServices from '@/service/user';
import { GetUserDto, GetUserInfoDto } from '@/dto/user';
export class UserController {
constructor(private readonly userService: UserServices) {}
// Get 请求 user/name?name=bricechou
async findByName( getUserDto: GetUserDto) {
return this.userService.read.findByName(getUserDto.name);
}
// Get 请求 user/info?id=123
async findById( getUserInfoDto: GetUserInfoDto) {
const user = await this.userService.read.findById(getUserInfoDto.id);
return { gender: user.gender, job: user.job };
}
}
// packages/node-server-demo/src/controller/log/add.ts
import { Controller, Post, Body } from '@nestjs/common';
import { AddLogDto } from '@/dto/log';
import LogServices from '@/service/log';
'log') (
export class CreateLogController {
constructor(private readonly logServices: LogServices) {}
// post('/log/add')
'add') (
create( () createLogDto: AddLogDto) {
return this.logServices.create.create(createLogDto);
}
}
-
Передача данныхОбъект передачи данных
// packages/node-server-demo/src/dto/user.ts
export class CreateUserDto {
name: string;
age: number;
gender: string;
job: string;
}
// 可以分开写,也可以合并
export class GetUserDto {
id?: number;
name: string;
}
// 可以分开写,也可以合并
export class GetUserInfoDto {
id: number;
}
-
класс обработки взаимодействия с базой данных службы
// packages/node-server-demo/src/service/user/read.ts
import { Injectable } from '@nestjs/common';
import { User } from '@/entities/User';
()
export class ReadUserService {
constructor() {}
async findByName(name: string): Promise<User> {
// 可以处理判空,从数据库读取/写入数据,可能会被多个 controller 进行调用
console.info('ReadUserService findByName > ', name);
return Promise.resolve({ id: 1, name, job: '程序员', gender: 1, age: 18 });
}
async findById(id: number): Promise<User> {
console.info('ReadUserService findById > ', id);
return Promise.resolve({
id: 1,
name: 'BriceChou',
job: '程序员',
gender: 1,
age: 18,
});
}
}
-
модуль регистрация модуля, класс обслуживания/класс управления
// packages/node-server-demo/src/module/user.ts
import { Module } from '@nestjs/common';
import UserService, { ReadUserService } from '@/service/user';
import { UserController } from '@/controller/user';
@Module({
providers: [UserService, ReadUserService],
controllers: [UserController],
})
export class UserModule {}
// packages/node-server-demo/src/module/index.ts 根模块注入
import { Module } from '@nestjs/common';
import { UserModule } from './user';
import { LogModule } from './log';
@Module({
imports: [
UserModule,
LogModule,
],
})
export class AppModule {}
-
main.js запускает все зарегистрированные классы
// packages/node-server-demo/src/main.ts
import { AppModule } from '@/module';
import { NestFactory } from '@nestjs/core';
import { NestExpressApplication } from '@nestjs/platform-express';
async function bootstrap() {
const app = await NestFactory.create<NestExpressApplication>(AppModule);
// 监听端口 3000
await app.listen(3000);
}
bootstrap();
-
Примечание. Вы должны установить пароль для установленной базы данных, а также у вас должен быть пароль для подключения к базе данных, в противном случае соединение с базой данных не удастся. -
Для MySQL нам нужно только установить базу данных.Если вы знакомы с инструкциями, вы можете просто управлять ею прямо из командной строки. -
Если вы с ним не знакомы, скачайте графический инструмент управления.
-
PRIMARY KEY 是表中的一个或多个列的组合,它用于唯一标识表中的每一行。 -
Not NULL 和 Unique 就不解释,就是直译的那个意思。 -
GENERATED 生成列是表中的一种特殊类型的列,它的值不是从插入语句中获取的,而是根据其他列的值通过一个表达式或函数生成的。
CREATE TABLE people (
first_name VARCHAR(100),
last_name VARCHAR(100),
full_name VARCHAR(200) AS (CONCAT(first_name, ' ', last_name))
);
-
UNS IGNED 这个数值类型就只能存储正数(包括零),不会存储负数。 -
ZEROFILL 将数值类型的字段的前面填充零,他会自动使字段变为 UNSIGNED,直到该字段达到声明的长度,如: 00007 -
BINARY 用于存储二进制字符串,如声明一个字段为 BINARY(5),那么存储在这个字段中的字符串都将被处理为长度为 5 的二进制字符串。
-
此外也可顺手创建一个索引,方便快速查找。
CREATE TABLE `rrweb`.`test_sys_req_log` (
`id` INT UNSIGNED NOT NULL AUTO_INCREMENT,
`content` TEXT NOT NULL,
`l_level` INT UNSIGNED NOT NULL,
`l_category` VARCHAR(255) NOT NULL,
`l_created_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
`l_updated_at` TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP,
PRIMARY KEY (`id`),
UNIQUE INDEX `id_UNIQUE` (`id` ASC) VISIBLE,
INDEX `table_index` (`l_level` ASC, `l_category` ASC, `l_time` ASC) VISIBLE);
3.连接数据库
-
安装 Sequelize
# 安装连接库
npm install --save @nestjs/sequelize sequelize sequelize-typescript mysql2
# 安装 type
npm install --save-dev @types/sequelize
-
配置数据库基础信息
// packages/node-server-demo/src/module/index.ts
import { Module } from '@nestjs/common';
import { UserModule } from './user';
import { LogModule } from './log';
import { Log } from '@/entities/Log';
import { SequelizeModule } from '@nestjs/sequelize';
@Module({
imports: [
SequelizeModule.forRoot({
dialect: 'mysql',
// 按数据库实际配置
host: '127.0.0.1',
// 按数据库实际配置
port: 3306,
// 按数据库实际配置
username: 'root',
// 按数据库实际配置
password: 'hello',
// 按数据库实际配置
database: 'world',
synchronize: true,
models: [Log],
autoLoadModels: true,
}),
LogModule,
UserModule,
],
})
export class AppModule {}
-
实体与数据库一一映射处理
import { getNow } from '@/common/date';
import {
Model,
Table,
Column,
PrimaryKey,
DataType,
} from 'sequelize-typescript';
'test_sys_req_log' }) ({ tableName:
export class Log extends Model<Log> {
({
type: DataType.INTEGER,
autoIncrement: true,
field: 'id',
})
id: number;
'content', type: DataType.TEXT }) ({ field:
content: string;
'l_level', type: DataType.INTEGER }) ({ field:
level: number; // 3严重,2危险,1轻微
'l_category' }) ({ field:
category: string; // 模块分类/来源分类
({
field: 'l_created_at',
type: DataType.NOW,
defaultValue: getNow(),
})
createdAt: number;
({
field: 'l_updated_at',
type: DataType.NOW,
defaultValue: getNow(),
})
updatedAt: number;
}
-
module 注册实体
// packages/node-server-demo/src/module/log.ts
import { Module } from '@nestjs/common';
import { SequelizeModule } from '@nestjs/sequelize';
import { Log } from '@/entities/Log';
import LogServices, {
CreateLogService,
UpdateLogService,
DeleteLogService,
ReadLogService,
} from '@/service/log';
import {
CreateLogController,
RemoveLogController,
UpdateLogController,
} from '@/controller/log';
@Module({
imports: [SequelizeModule.forFeature([Log])],
providers: [
LogServices,
CreateLogService,
UpdateLogService,
DeleteLogService,
ReadLogService,
],
controllers: [CreateLogController, RemoveLogController, UpdateLogController],
})
export class LogModule {}
-
service 操作数据库处理数据
import { Log } from '@/entities/Log';
import { Injectable } from '@nestjs/common';
import { AddLogDto } from '@/dto/log';
import { InjectModel } from '@nestjs/sequelize';
import { ResponseStatus } from '@/types/BaseResponse';
import { getErrRes, getSucVoidRes } from '@/common/response';
()
export class CreateLogService {
constructor(
(Log)
private logModel: typeof Log,
) {}
async create(createLogDto: AddLogDto): Promise<ResponseStatus<null>> {
console.info('CreateLogService create > ', createLogDto);
const { level = 1, content = '', category = 'INFO' } = createLogDto || {};
const str = content.trim();
if (!str) {
return getErrRes(500, '日志内容为空');
}
const item = {
level,
category,
// Tips: 为防止外部数据进行数据注入,我们可以对内容进行 encode 处理。
// content: encodeURIComponent(str),
content: str,
};
await this.logModel.create(item);
return getSucVoidRes();
}
}
-
C create 创建 -
R read 读取 -
U update 更新 -
D delete 删除
import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/sequelize';
import { User } from './user.model';
()
export class UserService {
constructor(
(User)
private userModel: typeof User,
) {}
// 创建新数据
async create(user: User) {
const newUser = await this.userModel.create(user);
return newUser;
}
// 查找所有数据
async findAll() {
return this.userModel.findAll();
}
// 按要求查找单个
async findOne(id: string) {
return this.userModel.findOne({ where: { id } });
}
// 按要求更新
async update(id: string, user: User) {
await this.userModel.update(user, { where: { id } });
return this.userModel.findOne({ where: { id } });
}
// 按要求删除
async delete(id: string) {
const user = await this.userModel.findOne({ where: { id } });
await user.destroy();
}
}
本文分享自微信公众号 - 京东云开发者(JDT_Developers)。
如有侵权,请联系 [email protected] 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一起分享。
{{o.name}}
{{m.name}}