你有一份NestJS入门指南,请查收(下)

简介: 你有一份NestJS入门指南,请查收(下)

连接 MySql 数据库



作为一个服务端框架那肯定离不开对数据库的操作,而 Nest 连接数据库以及操作数据库也是很简单的,毕竟我们有好用的工具啊,先安装

npm install @nestjs/typeorm typeorm mysql -S

然后在 app.module.ts 进行一个导入,配置一下自己的数据库用户名,密码等等,这里如果用本地数据库的话需要自己先在电脑安装数据库

import { Module } from "@nestjs/common";
import { AppController } from "./app.controller";
import { AppService } from "./app.service";
import { UserModule } from "./user/user.module";
import { TypeOrmModule } from "@nestjs/typeorm";
@Module({
  imports: [
    UserModule,
    TypeOrmModule.forRoot({
      type: "mysql",
      host: "localhost",
      port: 3306,
      username: "root",
      password: "root",
      database: "ceshi",
      entities: ["dist/**/*.entity{.ts,.js}"],
      synchronize: true,
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

然后我们可以到 user/entities/user.entity.ts 中简单建一个用户表

import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
@Entity("user")
export class UserEntity {
  @PrimaryGeneratedColumn()
  id: number; // 标记为主键,值自动生成
  @Column({ length: 20 })
  username: string;
  @Column({ length: 20 })
  password: string;
  @Column({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
  create_time: Date;
  @Column({ type: "timestamp", default: () => "CURRENT_TIMESTAMP" })
  update_time: Date;
}

保存过后就会发现 user 表就被自动创建了

image.png


CRUD



接下来我们根据前端传来的参数对数据库进行一个简单的 crud 操作,注意这里只是演示,少了一些逻辑判断。 首先在user.module.ts中导入数据库相关东西

import { Module } from "@nestjs/common";
import { UserService } from "./user.service";
import { UserController } from "./user.controller";
import { UserEntity } from "./entities/user.entity";
import { TypeOrmModule } from "@nestjs/typeorm";
@Module({
  imports: [TypeOrmModule.forFeature([UserEntity])],
  controllers: [UserController],
  providers: [UserService],
})
export class UserModule {}

来到create-user.dto.ts定义一下接收前端传来的参数

export class CreateUserDto {
  username: string;
  password: string;
}

然后在user.service.ts进行数据库数据的插入

import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { UserEntity } from './entities/user.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
@Injectable()
export class UserService {
  constructor(
    @InjectRepository(UserEntity)
    private userRepository: Repository<UserEntity>,
  ) {}
  async create(createUserDto: CreateUserDto) {
    this.userRepository.save(createUserDto);
    return await this.userRepository.save(createUserDto);
  }
}

在 ApiFox 模拟一个请求,会发现插入成功了

image.png

同时我们查看我们的 user 表出现了一条数据

image.png

我们再看一下查询,来到 user.service.ts 中的 findAll 方法

async findAll() {
    return await this.userRepository.find();
  }

因为 findAll 在 controller 中是 get 装饰,所以需要使用 get 请求

image.png

如果我们想加条件,可以这样写

async findAll() {
    return await this.userRepository.find({ where: { id: 1 } });
  }

对于数据的更新相对麻烦一点,比如我们想要更新一条数据可以这样写

user.controller.ts中我们需要接收前端传来的一个 id(动态路由传来的)以及 body

@Patch(':id')
  update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {
    return this.userService.update(+id, updateUserDto);
  }

然后在user.service.ts中的 update 方法中,根据 id 来更新前端传来的数据,注意这里用到了 TypeOrm 的查询构造器,想了解的可以到TypeOrm查看

async update(id: number, updateUserDto: UpdateUserDto) {
    const qb = await this.userRepository.createQueryBuilder();
    return await qb.update().set(updateUserDto).where({ id }).execute();
  }

我们可以使用Patch方法在 apiFox 中试一下

image.png

我们可以看到数据更新成功啦~

最后看一下删除,其实和更新差不多

async remove(id: number) {
    const qb = await this.userRepository.createQueryBuilder();
    return await qb.delete().where({ id }).execute();
  }

其实对于数据库操作的方法还有很多中,这里只是列举了其中的一小部分。想要熟练操作数据库还需要长期的日积月累才行


统一接口返回形式



通过上面的一通操作,细心的小伙汁肯定发现了上面接口返回的数据是个什么玩意.要状态没状态,要描述没描述的,这样拿给前端前端不得揍死你。所以为了把最好的留给前端,我们还需要对接口返回进行一个统一数据封装


一般接口返回的数据大致格式可能如下

{
    data:业务参数,
    code:状态码,
    describe:状态描述
    ...
}

首先我们使用命令新建一个过滤器,用来抛出我们需要返回给前端的错误码以告知前端传来的是错误请求

nest g filter common/filter/http-exception

然后修改一下http-exception.filter.ts

import {
  ExceptionFilter,
  Catch,
  ArgumentsHost,
  HttpException,
} from '@nestjs/common';
import { Request, Response } from 'express';
@Catch(HttpException)
export class HttpExceptionFilter implements ExceptionFilter {
  catch(exception: HttpException, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse<Response>();
    const request = ctx.getRequest<Request>();
    const status = exception.getStatus();
    response.status(status).json({
      code: status,
      timestamp: new Date().toISOString(),
      path: request.url,
    });
  }
}

在 main.ts 中注册

import { NestFactory } from "@nestjs/core";
import { AppModule } from "./app.module";
import { HttpExceptionFilter } from "./common/filter/http-exception/http-exception.filter";
async function bootstrap() {
  const app = await NestFactory.create(AppModule);
  //看这里看这里看这里~
  app.useGlobalFilters(new HttpExceptionFilter());
  await app.listen(3000);
}
bootstrap();

这时候我们随便找个接口抛出一个错误码试一下,就你了findAll方法

async findAll() {
    throw new HttpException('错误的请求', 401);
    return await this.userRepository.find();
  }

然后我们在 ApiFox 试一下

image.png

然后我们再创建一个拦截器对请求成功的数据进行格式化

同样的使用

nest g interceptor common/interceptor/transform

创建一个拦截器,直接把官网示例抄过来transform.interceptor.ts

import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
} from "@nestjs/common";
import { Observable } from "rxjs";
import { map } from "rxjs/operators";
export interface Response<T> {
  data: T;
}
@Injectable()
export class TransformInterceptor<T>
  implements NestInterceptor<T, Response<T>>
{
  intercept(
    context: ExecutionContext,
    next: CallHandler
  ): Observable<Response<T>> {
    return next
      .handle()
      .pipe(map((data) => ({ code: 200, data, describe: "请求成功" })));
  }
}

和过滤器一样在 main.ts 中注册

app.useGlobalInterceptors(new TransformInterceptor());

然后试一下查询接口

image.png


到这里我们就完成了返回结果的一个简单封装


写在最后



NestJS 的功能远远不止文章提到的这些,毕竟一个框架不是简单的一篇文章就能讲完的。就像本文标题一样,本篇文章旨在带领大家走进 NestJS 的大门,如果对 NestJS 感兴趣的小伙伴可以在以后的工作学习中慢慢探索,加油吧少年,祝你早日成为全干工程师!

需要文中代码的同学可以直接点击nest-template获取

相关文章
|
前端开发 JavaScript
【经典】全局公共scss文件的引入使用
【经典】全局公共scss文件的引入使用
|
JavaScript
VUE上传功能本地上传正常,打包上传后报错TypeError: ***.upload.addEventListener is not a function
VUE上传功能本地上传正常,打包上传后报错TypeError: ***.upload.addEventListener is not a function
1724 0
|
数据可视化 大数据 API
低代码可视化开发-uniapp新闻跑马灯组件-代码生成器
低代码可视化开发-uniapp新闻跑马灯组件-代码生成器
513 2
|
前端开发 Java 数据库
springBoot:template engine&自定义一个mvc&后端给前端传数据&增删改查 (三)
本文介绍了如何自定义一个 MVC 框架,包括后端向前端传递数据、前后端代理配置、实现增删改查功能以及分页查询。详细展示了代码示例,从配置文件到控制器、服务层和数据访问层的实现,帮助开发者快速理解和应用。
187 0
|
前端开发 NoSQL 数据库
Vue3 + Nest 实现权限管理系统 后端篇(三):基于RBAC 权限控制实现
RBAC(Role Based Access Control)是基于角色的权限控制,简单来说就是给用户赋予一些角色,那么该用户就会拥有这些角色的所有权限。接下来我们就用 NestJS 来实现基于 RBAC 的权限控制
720 0
Vue3 + Nest 实现权限管理系统 后端篇(三):基于RBAC 权限控制实现
|
前端开发 容器
css溢出隐藏的五种方法
css溢出隐藏的五种方法
278 1
|
设计模式 JavaScript 小程序
黑马程序员uni-app 小兔鲜儿 项目及bug记录(上)(1)
黑马程序员uni-app 小兔鲜儿 项目及bug记录(上)(1)
991 3
|
人工智能 JavaScript 开发工具
【完全免费】VS Code 最好用的 12 款 AI 代码提示插件!!!
🎉 探索12款免费VSCode AI代码提示插件:Codeium、Codegeex、CodeFuse、TONGYI Lingma、Comate、iFlyCode、Fitten Code、Bito AI、Mintlify Doc Writer、Kodezi AI、aiXcoder、IntelliCode。这些插件提供智能补全、代码生成、注释、优化,支持多种语言,提升编程效率!🚀👩‍💻👨‍💻
18454 0
|
Python
【Python】已解决:(pandas读取DataFrame列报错)raise KeyError(key) from err KeyError: (‘name‘, ‘age‘)
【Python】已解决:(pandas读取DataFrame列报错)raise KeyError(key) from err KeyError: (‘name‘, ‘age‘)
1808 0
uniapp 安装插件 uView (多平台快速开发的UI框架)
uniapp 安装插件 uView (多平台快速开发的UI框架)
739 0