新建项目
官方英文文档:https://nestjs.com/
中文网:https://nestjs.bootcss.com/
中文网2:https://docs.nestjs.cn/
$ npm i -g @nestjs/cli
$ nest new project-name
$ cd project-name
$ pnpm run start:dev
通过orm新建第一张表
- 安装必要包
$ npm i pnpm -g
$ npm i class-validator typeorm @nestjs/typeorm mysql
- 新建模块
$ nest g res users --no-spec
- 配置数据库 [edit file : app.module.ts]
import {
TypeOrmModule } from '@nestjs/typeorm';
@Module({
imports: [
UsersModule,
TypeOrmModule.forRoot({
type: 'mysql', //数据库类型
host: "localhost", //主机
port: 3306, //端口
username: "admin", //用户名
password: "123456", //密码
database: "nest_blog", //数据库名
autoLoadEntities: true, //自动加载模块
synchronize: true, // 同步:确保TypeORM实体每次运行应用程序时都会与数据库同步 !生产环境中时必须禁用! 会根据Entity生成mysql表格
logging: true // 打印日志 启动printSql()
}),
],
controllers: [AppController],
providers: [AppService],
})
- 添加第一个实体User [edit file : src/users/entities/user.entity.ts]
import {
Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, Unique, UpdateDateColumn } from "typeorm";
import {
Exclude } from "class-transformer";
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column({
type: "varchar", length: 128, comment: "用户名" })
username: string;
@Exclude()
@Column({
type: "varchar", length: 128, comment: "密码" })
password: string;
@Column({
type: "varchar", length: 255, comment: "用户头像", nullable: true })
avatarUrl: string;
@Column({
type: "varchar", length: 50, comment: "邮箱", nullable: true, unique: true })
email: string;
@Column({
type: "varchar", length: 20, comment: "手机号", nullable: true, unique: true })
phone: string;
@Column({
type: "varchar", length: 10, comment: "权限: admin user", default: "user" })
role: string
@CreateDateColumn()
createTime: Date;
@UpdateDateColumn()
updateTime: Date;
@Column({
nullable: true })
deleteTime: Date;
@Column({
comment: "是否已删除", default: false})
isDeleted: boolean = false;
}
- 引入实体 [edit file : src/users/users.module.ts]
import {
TypeOrmModule } from "@nestjs/typeorm";
import {
User } from "./entities/user.entity";
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UsersController],
providers: [UsersService],
})
- 运行后生成第一张数据表
$ pnpm run start:dev
实现第一个接口
- 添加user的创建和更新DTO(Data Transfer Object) [edit file : src/users/dto/create-user.dto.ts , /users/dto/update-user.dto.ts]
import {
IsBoolean, IsOptional, IsString } from "class-validator";
export class CreateUserDto {
@IsString()
readonly username: string;
@IsString()
readonly password: string;
@IsString()
@IsOptional()
readonly avatarUrl?: string;
@IsString()
@IsOptional()
readonly phone?: string;
@IsString()
@IsOptional()
readonly email?: string;
@IsString()
@IsOptional()
readonly role?: string;
@IsBoolean()
@IsOptional()
readonly isDeleted?: boolean;
}
import {
PartialType } from '@nestjs/mapped-types';
import {
CreateUserDto } from './create-user.dto';
// PartialType 用来 继承 CreateUserDto 的所有属性和验证规则并设置所有属性为可选
export class UpdateUserDto extends PartialType(CreateUserDto) {
}
- 修改接口文件 [edit file : src/users/]
import {
Injectable } from '@nestjs/common';
import {
CreateUserDto } from './dto/create-user.dto';
import {
UpdateUserDto } from './dto/update-user.dto';
import {
Repository } from "typeorm";
import {
User } from "./entities/user.entity";
import {
InjectRepository } from "@nestjs/typeorm";
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private readonly usersRepository: Repository<User>,
) {
}
create(createUserDto: CreateUserDto) {
const user = this.usersRepository.create(createUserDto);
return this.usersRepository.save(user);
}
}
User
是实体类,通常对应数据库中的一张表(在这里为user表),Repository<User>
则是TypeORM提供的一个类,它包含了诸如查找、保存、删除等操作数据库的方法,在这里专门用于操作User
实体的记录。
关于
usersRepository.save
方法:在数据库中保存给定的实体。如果数据库中不存在实体,则插入,否则更新。
开启请求参数校验和格式转换
- 安装必要包
$ pnpm i class-transformer
- 添加全局配置 [edit file : main.ts]
import {
NestFactory } from '@nestjs/core';
import {
AppModule } from './app.module';
import {
ValidationPipe } from "@nestjs/common";
async function bootstrap() {
const app = await NestFactory.create(AppModule);
app.useGlobalPipes(new ValidationPipe({
// 开启字段白名单验证 可以剔除掉上传对象中的不在DTO中的字段
whitelist: true,
// 当不在请求对象中包含不在白名单的字段时拒绝这个请求并提示 与 whitelist 组合使用
forbidNonWhitelisted: true,
// 开启DTO转换 使的 请求对象 与 DTO 匹配时的instanceof 为 true
// 如果@Param('id') id:number,transform配置将试图把id转化成number,而不是经由网络后的字符串id
transform: true,
transformOptions: {
// 开启全局隐式转换 可以省略@Type修饰符 隐式指定所有DTO都使用Type修饰符
enableImplicitConversion: true,
}
}));
await app.listen(3000);
}
bootstrap();
配置跨域
app.enableCors()
分页查询
- 新建DTO [create file : src/common/dto/pagination-query.dto.ts]
import {
IsOptional, IsPositive } from 'class-validator';
export class PaginationQueryDto {
// 检查值是否为大于零的正数。
@IsPositive()
@IsOptional()
page: number;
@IsPositive()
@IsOptional()
pageSize: number;
}
- 修改控制器 [edit file : src/users/users.controller.ts]
......
@Get()
findAll(@Query() paginationQuery: PaginationQueryDto) {
return this.usersService.findAll(paginationQuery);
}
......
- 修改服务 [edit file : src/users/users.service.ts]
......
findAll(paginationQuery: PaginationQueryDto) {
const {
page=1, pageSize=10} = paginationQuery
return this.usersRepository.find({
skip: (page - 1) * pageSize,
take: pageSize
});
}
......
实现简单的增删改查
import {
HttpException, HttpStatus, Injectable } from "@nestjs/common"
import {
CreateUserDto } from './dto/create-user.dto'
import {
UpdateUserDto } from './dto/update-user.dto'
import {
Repository } from "typeorm"
import {
User } from "./entities/user.entity"
import {
InjectRepository } from "@nestjs/typeorm"
import {
PaginationQueryDto } from "../common/dto/pagination-query.dto"
@Injectable()
export class UsersService {
constructor(
@InjectRepository(User)
private readonly usersRepository: Repository<User>
) {
}
create(createUserDto: CreateUserDto) {
const user = this.usersRepository.create(createUserDto)
return this.usersRepository.save(user)
}
findAll(paginationQuery: PaginationQueryDto) {
const {
page=1, pageSize=10} = paginationQuery
return this.usersRepository.find({
where: {
isDeleted: false},
skip: (page - 1) * pageSize,
take: pageSize
})
}
async findOne(id: number) {
const user = await this.usersRepository.findOne({
where: {
id}})
if (!user) throw new HttpException(`User #${
id} not found`, HttpStatus.