news 2026/4/18 12:49:35

NestJS 项目 - 快速生成 CRUD

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
NestJS 项目 - 快速生成 CRUD
CREATE TABLE `sys_banner` ( `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键', `image` varchar(255) DEFAULT NULL COMMENT '图片地址', `url` varchar(255) DEFAULT NULL COMMENT '跳转地址', `sort` int(1) DEFAULT '0' COMMENT '排序', `status` int(1) DEFAULT '1' COMMENT '状态 0=下架, 1=上架', `tenant_id` int(11) DEFAULT NULL COMMENT '租户ID', `deleted` bit(1) DEFAULT b'0' COMMENT '是否删除', `creator` varchar(64) DEFAULT NULL COMMENT '创建者', `updater` varchar(64) DEFAULT NULL COMMENT '更新者', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` datetime DEFAULT NULL COMMENT '更新时间', PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='轮播图';

1. 创建模块结构

使用 Nest CLI 快速生成 Banner 表模块:

命令行执行: nest g res banner

PS D:\Java\work\nodejs-demo\nest-admin> cd .\server\src\module\system\ PS D:\Java\work\nodejs-demo\nest-admin\server\src\module\system> nest g res banner ✔ What transport layer do you use? REST API ? Would you like to generate CRUD entry points? (Y/n) (按回车生成)

按Enter回车

PS D:\Java\work\nodejs-demo\nest-admin> cd .\server\src\module\system\ PS D:\Java\work\nodejs-demo\nest-admin\server\src\module\system> nest g res banner ✔ What transport layer do you use? REST API ✔ Would you like to generate CRUD entry points? Yes CREATE banner/banner.controller.ts (959 bytes) CREATE banner/banner.controller.spec.ts (596 bytes) CREATE banner/banner.module.ts (264 bytes) CREATE banner/banner.service.ts (661 bytes) CREATE banner/banner.service.spec.ts (478 bytes) CREATE banner/dto/create-banner.dto.ts (33 bytes) CREATE banner/dto/update-banner.dto.ts (181 bytes) CREATE banner/entities/banner.entity.ts (24 bytes) UPDATE system.module.ts (965 bytes) PS D:\Java\work\nodejs-demo\nest-admin\server\src\module\system>

选择配置:

  • Transport layer:REST API

  • Generate CRUD entry points:Yes

2. 生成的文件结构

banner/ ├── banner.controller.ts # 控制器 ├── banner.service.ts # 服务层 ├── banner.module.ts # 模块配置 ├── entities/ │ └── banner.entity.ts # 实体类 └── dto/ ├── create-banner.dto.ts # 创建 DTO └── update-banner.dto.ts # 更新 DTO

spec是测试类, 可忽略

3. 配置数据库实体

修改banner.entity.ts,映射数据库表:

import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm'; @Entity('sys_banner') export class Banner { @PrimaryGeneratedColumn() id: number; @Column({ length: 255, nullable: true, comment: '图片地址' }) image: string; @Column({ length: 255, nullable: true, comment: '跳转地址' }) url: string; @Column({ default: 0, comment: '排序' }) sort: number; @Column({ default: 1, comment: '状态 0=下架, 1=上架' }) status: number; @Column({ nullable: true, comment: '租户ID' }) tenant_id: number; @Column({ default: false, comment: '是否删除' }) deleted: boolean; @Column({ length: 64, nullable: true, comment: '创建者' }) creator: string; @Column({ length: 64, nullable: true, comment: '更新者' }) updater: string; @Column({ type: 'datetime', nullable: true, comment: '创建时间' }) create_time: Date; @Column({ type: 'datetime', nullable: true, comment: '更新时间' }) update_time: Date; }

4. 配置 DTO 数据验证

create-banner.dto.ts

import { IsString, IsOptional, IsInt, IsBoolean, IsUrl } from 'class-validator'; export class CreateBannerDto { @IsString() image: string; @IsOptional() @IsUrl() url?: string; @IsOptional() @IsInt() sort?: number; @IsOptional() @IsInt() status?: number; @IsOptional() @IsInt() tenant_id?: number; }

update-banner.dto.ts

已经继承CreateBannerDto

import { PartialType } from '@nestjs/mapped-types'; import { CreateBannerDto } from './create-banner.dto'; export class UpdateBannerDto extends PartialType(CreateBannerDto) {}

5. 服务层逻辑

banner.service.ts核心方法:

import { Injectable } from '@nestjs/common'; import { InjectRepository } from '@nestjs/typeorm'; import { Repository } from 'typeorm'; import { Banner } from './entities/banner.entity'; import { CreateBannerDto } from './dto/create-banner.dto'; import { UpdateBannerDto } from './dto/update-banner.dto'; @Injectable() export class BannerService { constructor( @InjectRepository(Banner) private bannerRepository: Repository<Banner>, ) {} create(createBannerDto: CreateBannerDto) { return this.bannerRepository.save(createBannerDto); } findAll() { return this.bannerRepository.find({ where: { deleted: false }, order: { sort: 'ASC' } }); } findOne(id: number) { return this.bannerRepository.findOneBy({ id, deleted: false }); } update(id: number, updateBannerDto: UpdateBannerDto) { return this.bannerRepository.update(id, { ...updateBannerDto, update_time: new Date() }); } remove(id: number) { // 软删除 return this.bannerRepository.update(id, { deleted: true, update_time: new Date() }); } }

6. 控制器路由

banner.controller.ts

import { Controller, Get, Post, Body, Patch, Param, Delete } from '@nestjs/common'; import { BannerService } from './banner.service'; import { CreateBannerDto } from './dto/create-banner.dto'; import { UpdateBannerDto } from './dto/update-banner.dto'; @Controller('banner') export class BannerController { constructor(private readonly bannerService: BannerService) {} @Post() create(@Body() createBannerDto: CreateBannerDto) { return this.bannerService.create(createBannerDto); } @Get() findAll() { return this.bannerService.findAll(); } @Get(':id') findOne(@Param('id') id: string) { return this.bannerService.findOne(+id); } @Patch(':id') update(@Param('id') id: string, @Body() updateBannerDto: UpdateBannerDto) { return this.bannerService.update(+id, updateBannerDto); } @Delete(':id') remove(@Param('id') id: string) { return this.bannerService.remove(+id); } }

7. 模块配置

banner.module.ts

import { Module } from '@nestjs/common'; import { TypeOrmModule } from '@nestjs/typeorm'; import { BannerService } from './banner.service'; import { BannerController } from './banner.controller'; import { Banner } from './entities/banner.entity'; @Module({ imports: [TypeOrmModule.forFeature([Banner])], controllers: [BannerController], providers: [BannerService], }) export class BannerModule {}

8. 自动注册到 SystemModule

Nest CLI 会自动更新system.module.ts

import { Module } from '@nestjs/common'; import { BannerModule } from './banner/banner.module'; @Module({ imports: [BannerModule], // 自动添加 }) export class SystemModule {}

9. 接口测试

生成的 REST API:

GET /banner # 获取所有轮播图 GET /banner/:id # 获取单个轮播图 POST /banner # 创建轮播图 PATCH /banner/:id # 更新轮播图 DELETE /banner/:id # 删除轮播图(软删除)

总结

通过nest g res命令可以快速生成标准的 CRUD 模块,包含:

  • 完整的 REST API 接口

  • TypeORM 实体映射

  • 基本的 DTO 验证

  • 模块化的代码结构

后续可根据业务需求添加:

  • 权限控制(@Roles() 装饰器)

  • 数据验证管道

  • 日志记录

  • 缓存机制

  • 文件上传处理

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/17 20:18:06

CFD后处理终极指南:ANSYS Fluent实战技巧全解析

CFD后处理终极指南&#xff1a;ANSYS Fluent实战技巧全解析 【免费下载链接】CFD-POST后处理教程 这是一份专为ANSYS Fluent用户设计的CFD-POST后处理教程&#xff0c;源自安世亚太的内部培训教材。教程详细介绍了CFD-POST的核心工具&#xff0c;包括等值面、速度矢量图和等值线…

作者头像 李华
网站建设 2026/4/17 2:49:58

ComfyUI-SeedVR2视频超分辨率终极指南:从模糊到高清的完美蜕变

ComfyUI-SeedVR2视频超分辨率终极指南&#xff1a;从模糊到高清的完美蜕变 【免费下载链接】ComfyUI-SeedVR2_VideoUpscaler Non-Official SeedVR2 Vudeo Upscaler for ComfyUI 项目地址: https://gitcode.com/gh_mirrors/co/ComfyUI-SeedVR2_VideoUpscaler 还在为模糊的…

作者头像 李华
网站建设 2026/4/18 11:32:01

DOSBox-X终极指南:跨平台DOS模拟器完整使用教程

DOSBox-X终极指南&#xff1a;跨平台DOS模拟器完整使用教程 【免费下载链接】dosbox-x DOSBox-X fork of the DOSBox project 项目地址: https://gitcode.com/gh_mirrors/do/dosbox-x 在数字复古浪潮席卷全球的今天&#xff0c;DOSBox-X作为一款功能强大的跨平台DOS模拟…

作者头像 李华
网站建设 2026/4/18 3:46:22

跨平台歌单迁移终极攻略:三分钟解锁音乐自由

还在为音乐平台的切换而头疼吗&#xff1f;当你从网易云音乐转战Apple Music&#xff0c;或是从QQ音乐投向Spotify的怀抱&#xff0c;最令人困扰的就是精心收藏的歌单无法随身携带。现在&#xff0c;GoMusic项目为你提供了完美的解决方案&#xff0c;这个基于Golang和Vue技术栈…

作者头像 李华
网站建设 2026/4/18 8:01:27

10分钟上手Glide.js配置生成器:让轮播开发效率提升300%

10分钟上手Glide.js配置生成器&#xff1a;让轮播开发效率提升300% 【免费下载链接】glide 项目地址: https://gitcode.com/gh_mirrors/glidej/Glide.js 还在为轮播组件的参数配置而头疼吗&#xff1f;是否因反复调整autoplay时长与swipeThreshold阈值而浪费时间&#…

作者头像 李华
网站建设 2026/4/17 21:10:17

PyTorch-CUDA-v2.6镜像是否支持自动驾驶感知模块开发?

PyTorch-CUDA-v2.6镜像在自动驾驶感知开发中的适配性分析 在智能驾驶研发进入快车道的今天&#xff0c;环境感知算法的迭代效率直接决定了整车系统的安全性和智能化水平。作为感知模块的核心——基于深度学习的目标检测、语义分割与多模态融合模型&#xff0c;其训练和推理对算…

作者头像 李华