初始化项目
安装依赖
npm i -g @nest/cli
新建项目
nest new project-name
命令行创建
创建Controller:nest g co test
创建Module:nest g mo test
创建Service:nest g service test
请求创建
123123
接口文档swagger
安装依赖
npm install @nestjs/swagger swagger-ui-express
装饰器
Controller装饰器:@ApiTags("Controller标签")
Controller装饰器:@ApiBearerAuth(),用于token鉴权,在文档页设置token
Api装饰器:@ApiOperation({ summary: 'Api摘要', description: 'Api描述' })
模型字段装饰器:@ApiProperty({ description: '字段描述' }),字段必填
模型字段装饰器:@ApiPropertyOptional({ description: '字段描述' }),字段非必填
注册使用
typescript
// main.ts
import { NestFactory } from '@nestjs/core';
import { AppModule } from './app.module';
import {
DocumentBuilder,
SwaggerDocumentOptions,
SwaggerModule,
} from '@nestjs/swagger';
const app = await NestFactory.create(AppModule, { cors: true });
const swaggerOption = new DocumentBuilder()
.setTitle('接口文档') // 文档标题
.setDescription('用来展示API信息') // 文档描述
.setVersion('1.0') // 文档版本号
.addTag('') // 标签
.addBearerAuth() // token鉴权
.build();
const document = SwaggerModule.createDocument(app, swaggerOption);
// 第一个参数是文档访问路径前缀
SwaggerModule.setup('doc', app, document);
await app.listen(3000);
// 访问文档路径:http://localhost:3000/doc
管道(验证)
安装依赖
npm install class-validator class-transformer
装饰器
模型字段装饰器:@IsNotEmpty({ message: "xxx字段为必填项" })
常用方法
typescript
import { isBoolean, isNumber, isArray, validate} from 'class-validator';
import { plainToClass } from 'class-transformer';
// isBoolean 是否为布尔值
// isNumber 是否为数字
// isArray 是否为数组
// validate 验证配置的验证规则
// plainToClass 将对象转换为Class,用以获取验证规则进行验证
注册使用
管道使用需要注册:
在main.ts中全局注册管道:
typescript
// main.ts
import { ValidationPipe } from '@nestjs/common';
app.useGlobalPipes(new ValidationPipe());
数据库操作(TypeORM+MySql)
安装依赖
npm i typeorm mysql
数据源
实体
装饰器
实体是由@Entity
装饰器装饰的模型。
typescript
// name对应数据库表名,schema对应数据库名,name可简写
@Entity({name:"table_name",schema:"schema_name"})
@Entity({"table_name",schema:"schema_name"})
表列是由@Column
装饰器装饰的实体属性。
主列是由@PrimaryColumn
装饰器装饰的实体属性。
自动生成的列是由@PrimaryGeneratedColumn
装饰器装饰的实体属性。
列数据类型
数据类型一般会根据实体属性定义的类型进行推断,如:number将被转换为integer,string将转换为varchar,boolean转换为bool等。也可以自行设置,如下:
typescript
// type可以简写
@Column("int")
@Column({type: "int"})
@Colunm("int", {name: "field_name", length: 100, unique: true, ...})
更多配置。
关系
typescript
import { Entity, Column, PrimaryGeneratedColumn, ManyToOne, OneToMany, OneToOne, JoinColumn } from "typeorm";
@Entity()
export class Category {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
description: string;
@OneToOne(type => Category)
@JoinColumn()
item: Category;
@OneToMany(type => Category, category => category.children)
parent: Category;
@ManyToOne(type => Category, category => category.parent)
children: Category;
}
@OneToOne
:一对一
@OneToMany
:一对多,总是包含反向关系,不能单独出现,需要和@ManyToOne一起使用,关系拥有者为多对一的一侧
@ManyToOne
:多对一
@JoinColumn
:实体键的对应关系,仅在关系的一侧使用,关系拥有者使用,关系的拥有方包含数据库中具有外键的列
TODO:多对多比较复杂,还需研究
@ManyToMany
:多对多
@JoinTable()
:需要指定这是关系的所有者方
参数1,type=>Category,返回当前实体想要建立关系的目标实体类
参数2,category=>category.xxx,用以指定反向关系,当前实体存储在目标实体的xxx属性
Entity Manager 和 Repository
Entity Manager,实体管理器,可以管理(insert, update, delete, load 等)任何实体。EntityManager 就像放一个实体存储库的集合的地方。
Repository就像EntityManager一样,但其操作仅限于具体实体。