nest守卫 装饰器 swagger

nest守卫 装饰器 swagger typeorm数据库连接

nest g gu  创建守卫

controller中引入

  @UseGuards(UserGuard) // 可以放在方法上也可以放在类上
  @SetMetadata('role','admin')//放在类上 检验是否拥有role权限admin 

guard中注入 反射

  constructor(private Relector:Reflector){}
  
  //此方式拿到类源信息
const admin = this.Relector.get('role',context.getHandler())

自定义装饰器类似于java 的自定义注解

nest g d 

其实就是封装了一下SetMetadata

import { SetMetadata } from '@nestjs/common';

export const Role = (...args: string[]) => SetMetadata('role', args);

自定义参数装饰器

export const ReqUrl = createParamDecorator((data:string,ctx:ExecutionContext) =>{
    return ctx.switchToHttp().getRequest<Request>().originalUrl
})

//使用
  findAll(@ReqUrl() url:string) 

swagger接口文档

依赖

npm install @nestjs/swagger swagger-ui-exp

main.ts 中引入

  const options = new DocumentBuilder().setTitle('小海海').setDescription('一段迷人的描述').setVersion('1').build()
  const document = SwaggerModule.createDocument(app,options)
  SwaggerModule.setup('/api-docs',app,document)
@ApiTags()   // 分组的 放在 controller类上
@ApiOperation({summary:'描述',description:'额描述'})  // 接口描述的
@ApiParam()
@Apiquery
@Apiresponse() //添加在controller方法中的 描述了该方法的返回了些什么东西
@Apipropertiy()// DTO上面描述字段的
@ApiBearerAuth() // 这个很重要  JTW验证 可以自动给你添加token    需要在main中配置

typeorm

npm install -- save @nestjs/typeorm typeorm mysql2

module 中 imports 引入

TypeOrmModule.forRoot({
    type:'mysql',
    username:'root',
    password:'1234',
    host:'192.168.2.2',
    database:'test',
    port:3306,
    autoLoadEntities:true,
    synchronize:true
  })

建立entry 这个是与数据库对应的 用来建表的

import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";

@Entity()
export class Shop {

    @PrimaryGeneratedColumn()
    id:string
    @Column()
    name:string
    @Column()
    price:number
    @Column()
    describe:string
}

建立DTO (data translation object) 这个是与数据传输有关的

import { IsNumber, IsString } from "class-validator"

export class CreateShopDto {

    @IsString()
    name:string
    @IsNumber()
    price:number
    @IsString()
    describe:string
}

接下来在模块中引入

  imports:[TypeOrmModule.forFeature([Shop])],

service 中使用工厂方法

import { Injectable, NotFoundException } from '@nestjs/common';
import { CreateShopDto } from './dto/create-shop.dto';
import { UpdateShopDto } from './dto/update-shop.dto';
import { InjectRepository} from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Shop } from './entities/shop.entity';
@Injectable()
export class ShopService {
  constructor(@InjectRepository(Shop) private readonly repository:Repository<Shop>){}
  create(createShopDto: CreateShopDto) {
    const shop =this.repository.create(createShopDto)
    return this.repository.save(shop)
  }

  findAll() {
    return this.repository.find()
  }

 async findOne(id: string) {
    const shop = await this.repository.findOneBy({id:id})
    if(shop == undefined){
      throw new NotFoundException('meizhaodao ')
    }
    return shop
  }

  async update(id: string, updateShopDto: UpdateShopDto) {
    console.log(id);
    
    const shop = await this.repository.findOneBy({id})
    if(updateShopDto.describe != null){
      shop.describe = updateShopDto.describe
    }
    if(updateShopDto.name != null){
      shop.name = updateShopDto.name
    }
    if(updateShopDto.price != null){
      shop.price = updateShopDto.price
    }
    if(shop === undefined){
      throw new NotFoundException('meizhaodao ')
    }
    return this.repository.save(shop)
  }

  async remove(id: string) {
    const shop = await this.repository.preload({
      id
    })
    if(shop == undefined){
      throw new NotFoundException('meizhaodao ')
    }
    return this.repository.remove(shop)
  }
}




数据库关系 一对一(OneToOne) 一对多(OneToMany)多对多(ManytoMany)

以此为例子 shop中添加一个features的数组

import { type } from "os";
import { Column, Entity, JoinTable, ManyToMany, PrimaryGeneratedColumn } from "typeorm";
import { Feature } from "./feature.entity";

@Entity()
export class Shop {

    @PrimaryGeneratedColumn()
    id:string
    @Column()
    name:string
    @Column()
    price:number
    @Column()
    describe:string

    @JoinTable()
    @ManyToMany(type => Feature,(feature) => feature.shops)
    features:string[]
}

添加一个特性 通过 @ManyToMany(type => Feature,(feature) => feature.shops) 相关联 他会自动创建表格

nest g class /path/feature.eneity
import { type } from "os";
import { Column, Entity, ManyToMany, PrimaryColumn } from "typeorm";
import { Shop } from "./shop.entity";

@Entity()
export class Feature {

    @PrimaryGeneratedColumn()
    id:number

    @Column()
    name:string

    @ManyToMany(type => Shop, shop=>shop.features)
    shops:Shop[]
}

不要忘记在模块中注入 Feature

imports:[TypeOrmModule.forFeature([Shop,Feature])],

于是乎你的查询就需要改变了

通过给定的options

  findAll() {
    return this.repository.find({
      relations:['features']
    })
  }

creat update

给shop 实体的feature注解添加参数 cascade:true 并将类型改为 Feature

    @JoinTable()
    @ManyToMany(type => Feature,(feature) => feature.shops,{
        cascade:true
    })
    features:Feature[]

在service中注入 Feature的工厂方法并添加 相关的查找方法

 @InjectRepository(Feature) private readonly featureRespository:Repository<Feature>
   
   
   
     async perloadFetaure(name: string): Promise<Feature> {
    const featuer = await this.featureRespository.findOneBy({ name: name })
   // 如果有就直接返回
    if (featuer) {

      return featuer
    }
   //没有的话则添加一个由于开启了cascade:true 所以不需要save 他会自动添加
    return this.featureRespository.create({ name: name })
  }

改造create方法

async create(createShopDto: CreateShopDto) {


    const features = await Promise.all(
      createShopDto.features.map(name => this.perloadFetaure(name))
    )

    const shop = this.repository.create({
      ...createShopDto,
      features
    })
    
    return this.repository.save(shop)
  }

改造updata 方法

  async update(id: string, updateShopDto: UpdateShopDto) {

    console.log(id);
    const features = updateShopDto.features && (await Promise.all(
      updateShopDto.features.map(name => this.perloadFetaure(name))
    ))

    const shop = await this.repository.preload({
      id: +id,
      ...updateShopDto,
      features
    })
    if (shop === undefined) {
      throw new NotFoundException('meizhaodao ')
    }
    return this.repository.save(shop)
  }

分页

首先添加一个公共的类

nest g class common/dto/pagination-query.dto --no-spec
import { Type } from "class-transformer"
import { IsOptional, IsPositive } from "class-validator"

export class PaginationQueryDto {

    @IsOptional()//可选的 没有的话不至于报错
    @IsPositive()// 确保是个正数
    @Type(() =>Number) //由于传输的都是字符串 所以开启这个装饰器 使其变为数字   这个可以去掉如果说 在main中配置了全局的类型隐式转换
    limit:number

    @IsOptional()
    @IsPositive()
    @Type(() =>Number)
    offset:number
}

/全局类型隐式转换/

  app.useGlobalPipes(new ValidationPipe({
    //whitelist:true,
    transform:true,
    transformOptions:{
      enableImplicitConversion:true
    }
  }))

改造 findAll方法

service中 skip 与 take 来实现分页

  @Get()
  findAll(@Query()paginationQueryDto:PaginationQueryDto) {
    return this.shopService.findAll(paginationQueryDto);
  }
  
  /*service*/
    findAll(paginationQueryDto:PaginationQueryDto) {
    const { limit ,offset} = paginationQueryDto
    return this.repository.find({
      relations: ['features'],
      skip:offset,
      take:limit
    })
  }
  
  
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值