NestJS 3 分钟搭好 MySQL + MongoDB,CRUD 复制粘贴直接运行

基于上一篇内容《为什么现代 Node 后端都选 NestJS + TypeScript?这组合真香了》,这篇文章继续写数据库的连接。

所以今天把MySQL、MongoDB全接上,做个小实例。朋友们项目里用什么数据库可以视情况而定。
这里的功能分别为:

  • MySQL:存用户
  • MongoDB:存日志

代码短、跟着敲就行。

1. 生成对应架构

执行以下命令生成相关模块代码(Module/Service/Controller)

nest g res user
nest g res log

2. 装包

pnpm i @nestjs/typeorm typeorm mysql2
pnpm i @nestjs/mongoose mongoose

3. 连库

app.module.ts 一次配好

import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { MongooseModule } from '@nestjs/mongoose';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { TodoModule } from './todo/todo.module';
import { UserModule } from './user/user.module';
import { LogModule } from './log/log.module';@Module({imports: [// MySQLTypeOrmModule.forRoot({type: 'mysql',host: 'localhost',port: 3306,username: 'root',password: 'SV^u8@rB8',database: 'demo',autoLoadEntities: true,synchronize: true, // 仅本地用,生产关掉}),// MongoDBMongooseModule.forRoot('mongodb://localhost:27017/test'),// 业务模块TodoModule,UserModule,LogModule,],controllers: [AppController],providers: [AppService],
})
export class AppModule {}

代码生成了,接下来我们来处理数据库和增删改查的代码。

Mysql

1. 实体和数据表

数据库表
CREATE TABLE `user` (`id` bigint NOT NULL AUTO_INCREMENT COMMENT '主键',`name` varchar(255) COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '用户名',`age` int DEFAULT NULL COMMENT '年龄',PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='用户表';
MySQL 实体
// user.entity.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';@Entity()
export class User {@PrimaryGeneratedColumn() id: number;@Column() name: string;@Column() age: number;
}
Dto
// create-user.dto.ts
export class CreateUserDto {name: string;age: number;
}

这里容易出现一个Eslint问题的爆红,如下图:

出现这种情况执行以下命令:

npx eslint "src/**/*.{ts,js}" --fix --ext .ts,.js

如果还是不行,再执行下这个

npx prettier --write "src/**/*.{ts,js,json}"

2. 业务代码(cv即可)

user.controller.ts
import { Controller, Get, Post, Body, Patch, Param, Delete,} from '@nestjs/common';
import { UserService } from './user.service';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';@Controller('user')
export class UserController {constructor(private readonly userService: UserService) {}@Post()create(@Body() createUserDto: CreateUserDto) {return this.userService.create(createUserDto);}@Get()findAll() {return this.userService.findAll();}@Get(':id')findOne(@Param('id') id: string) {return this.userService.findOne(+id);}@Patch(':id')update(@Param('id') id: string, @Body() updateUserDto: UpdateUserDto) {return this.userService.update(+id, updateUserDto);}@Delete(':id')remove(@Param('id') id: string) {return this.userService.remove(+id);}
}
user.module.ts

这里稍微的修改了一下,引入了TypeOrmModule

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

完成了增删改查的业务代码

import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { User } from './entities/user.entity';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';@Injectable()
export class UserService {constructor(@InjectRepository(User)private readonly repo: Repository<User>,) {}async create(createUserDto: CreateUserDto): Promise<User> {return await this.repo.save(createUserDto);}async findAll(): Promise<User[]> {return await this.repo.find();}async findOne(id: number): Promise<User> {const user = await this.repo.findOne({ where: { id } });if (!user) {throw new Error(`User with ID ${id} not found`);}return user;}async update(id: number, updateUserDto: UpdateUserDto): Promise<User> {const user = await this.findOne(id);Object.assign(user, updateUserDto);return await this.repo.save(user);}async remove(id: number): Promise<void> {const user = await this.findOne(id);await this.repo.remove(user);}
}

3. 跑起来,测试下接口

npm run start

新增

POST http://localhost:3000/user

{ "name": "张三", "age": 30 }

修改

POST http://localhost:3000/user

{ "id": 1, "name": "张三", "age": 31 }

删除

DELETE http://localhost:3000/user/1

查询

GET http://localhost:3000/user/1

这里实现mysql的增删改查就完成了

MongoDB

大致流程和mysql是一样的,写法稍微有些差别

1. 实体和集合

创建一个集合
db.createCollection("logs");
集合 实体
// log.entity.ts
import { Prop, Schema, SchemaFactory } from '@nestjs/mongoose';
import { Document, Types } from 'mongoose';export type LogDocument = Log & Document;@Schema()
export class Log {_id?: Types.ObjectId;@Prop({ required: true })message: string;@Prop({ default: Date.now })timestamp: Date;
}export const LogSchema = SchemaFactory.createForClass(Log);
Dto
// create-log.dto.ts
export class CreateLogDto {message: string;timestamp?: Date;
}

2. 业务代码(cv即可)

log.controller.ts
import {Controller, Get, Post, Body, Patch, Param, Delete} from '@nestjs/common';
import { LogService } from './log.service';
import { CreateLogDto } from './dto/create-log.dto';
import { UpdateLogDto } from './dto/update-log.dto';@Controller('log')
export class LogController {constructor(private readonly logService: LogService) {}@Post()create(@Body() createLogDto: CreateLogDto) {return this.logService.create(createLogDto);}@Get()findAll() {return this.logService.findAll();}@Get(':id')findOne(@Param('id') id: string) {return this.logService.findOne(id);}@Patch(':id')update(@Param('id') id: string, @Body() updateLogDto: UpdateLogDto) {return this.logService.update(id, updateLogDto);}@Delete(':id')remove(@Param('id') id: string) {return this.logService.remove(id);}
}
log.module.ts

引入了MongooseModule

import { Module } from '@nestjs/common';
import { MongooseModule } from '@nestjs/mongoose';
import { LogService } from './log.service';
import { LogController } from './log.controller';
import { Log, LogSchema } from './entities/log.entity';@Module({imports: [MongooseModule.forFeature([{ name: Log.name, schema: LogSchema }])],controllers: [LogController],providers: [LogService],
})
export class LogModule {}
user.service.ts

增删改查的业务代码

import { Injectable } from '@nestjs/common';
import { InjectModel } from '@nestjs/mongoose';
import { Model } from 'mongoose';
import { CreateLogDto } from './dto/create-log.dto';
import { UpdateLogDto } from './dto/update-log.dto';
import { Log, LogDocument } from './entities/log.entity';@Injectable()
export class LogService {constructor(@InjectModel(Log.name) private logModel: Model<LogDocument>) {}async create(createLogDto: CreateLogDto): Promise<Log> {const createdLog = new this.logModel(createLogDto);return createdLog.save();}async findAll(): Promise<Log[]> {return this.logModel.find().exec();}async findOne(id: string): Promise<Log> {const log = await this.logModel.findById(id).exec();if (!log) {throw new Error(`Log with ID ${id} not found`);}return log;}async update(id: string, updateLogDto: UpdateLogDto): Promise<Log> {const updatedLog = await this.logModel.findByIdAndUpdate(id, updateLogDto, { new: true }).exec();if (!updatedLog) {throw new Error(`Log with ID ${id} not found`);}return updatedLog;}async remove(id: string): Promise<void> {const result = await this.logModel.findByIdAndDelete(id).exec();if (!result) {throw new Error(`Log with ID ${id} not found`);}}
}

3. 启动,测试接口

npm run start

新增

POST http://localhost:3000/log

{ "message": "张三的消息" }

修改

POST http://localhost:3000/log

{ "id": 1, "message": "李四的消息"}

删除

DELETE http://localhost:3000/log/1

查询

GET http://localhost:3000/log/1

MongoDB的增删改查完成

小结

  • MySQL:使用TypeORM实体一把梭
  • MongoDB:使用Schema装饰器直接上

NestJS真的是结构清晰,开发很快,再也不用从头造轮子了。

我是大华,专注分享前后端开发的实战笔记。关注我,少走弯路,一起进步!

📌往期精彩

《Elasticsearch 太重?来看看这个轻量级的替代品 Manticore Search》

《别再if套if了!Java中return的9种优雅写法》

《别学23种了!Java项目中最常用的6个设计模式,附案例》

《写给小公司前端的 UI 规范:别让页面丑得自己都看不下去》

《Vue3+TS设计模式:5个真实场景让你代码更优雅》

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/95552.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/95552.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

用了企业微信 AI 半年,这 5 个功能让我彻底告别重复劳动

每天上班不是在整理会议纪要&#xff0c;就是在翻聊天记录找文件&#xff0c;写文档还要自己抠数据…… 这些重复劳动是不是也在消耗你的时间&#xff1f;作为用了企业微信 AI 功能半年的 “老用户”&#xff0c;我必须说&#xff1a;企业微信 AI 的这 5 个功能&#xff0c;真的…

从入门到高手,Linux就应该这样学【好书推荐】

从入门到高手&#xff0c;请这样学Linux 一、Linux基础与终端操作 1.1 Linux简介 Linux 是一种开源的类 Unix 操作系统&#xff0c;以其稳定性、安全性和高效性被广泛应用于服务器、嵌入式系统及开发环境中。掌握基本命令和操作技巧是 Linux 学习的关键。 1.2 终端基础 打开…

【数据可视化-104】安徽省2025年上半年GDP数据可视化分析:用Python和Pyecharts打造炫酷大屏

&#x1f9d1; 博主简介&#xff1a;曾任某智慧城市类企业算法总监&#xff0c;目前在美国市场的物流公司从事高级算法工程师一职&#xff0c;深耕人工智能领域&#xff0c;精通python数据挖掘、可视化、机器学习等&#xff0c;发表过AI相关的专利并多次在AI类比赛中获奖。CSDN…

组件库UI自动化

一、背景 背景&#xff1a; 组件库全局改动场景多&#xff0c;组件之间耦合场景多–时常需要全场景回归组件库demo有200多个&#xff0c;手动全局回归耗时耗力细微偏差纯视觉无法辨别 可行性分析&#xff1a; 组件库功能占比 L1&#xff08;视觉层&#xff09;&#xff1a;图片…

面试题:JVM与G1要点总结

一.Java内存区域 1.运行时数据区的介绍 2.站在线程的角度看Java内存区域 3.深入分析堆和栈的区别 4.方法的出入栈和栈上分配、逃逸分析及TLAB 5.虚拟机中的对象创建步骤 6.对象的内存布局 1.运行时数据区的介绍 运行时数据区的类型&#xff1a;程序计数器、Java虚拟机栈、本地方…

车辆安全供电系统开发原则和实践

摘要在汽车行业中&#xff0c;安全应用的重要性在不断提升&#xff0c;例如受车辆自动化发展以及机械备用系统重要性降低的影响。为应对这些趋势&#xff0c;安全相关的电气和 / 或电子系统&#xff08;E/E 系统&#xff09;的电源输入必须由供电系统来保障&#xff0c;这使得功…

WebSocket客户端库:websocket-fruge365

&#x1f680; 从零开始打造一个WebSocket客户端库&#xff1a;websocket-fruge365 &#x1f4d6; 前言 在现代Web开发中&#xff0c;实时通信已经成为不可或缺的功能。无论是聊天应用、实时数据监控&#xff0c;还是在线协作工具&#xff0c;WebSocket都扮演着重要角色。然而…

rocketmq批量执行跑批任务报错

rocketmq批量执行跑批任务&#xff0c;报下面的错误&#xff0c;怎么处理一下呢&#xff1f;是修改配置还是修改代码还是&#xff1f; org.apache.rocketmq.client.exception.MQBrokerException: CODE: 215 DESC: [FLOW]client has exhausted the send quota for the current …

大语言模型(LLM)简介与应用分享

1. 什么是大语言模型&#xff08;LLM&#xff09; 大语言模型&#xff08;Large Language Model&#xff0c;简称 LLM&#xff09;是基于 深度学习 和 海量文本数据 训练而成的人工智能模型。 采用 Transformer 架构参数规模巨大&#xff08;数十亿到数千亿&#xff09;能够 理…

【算法笔记】选择排序、插入排序、冒泡排序、二分查找问题

算法的笔记&#xff0c;直接上代码&#xff0c;思路和问题这些&#xff0c;都在代码注释上面 1、工具类 为了生成测试代码和比较器&#xff0c;专门写了一个数组工具类&#xff0c;代码如下&#xff1a; /*** 数组工具类*/ public class ArrUtil {/*** 生成随机数组* 长度是[0,…

行业分享丨基于SimSolid的大型汽车连续冲压模具刚度分析

*本文投稿自机械零部件制造业用户 汽车连续模具的刚度直接决定了冲压件质量&#xff08;尺寸精度、表面缺陷&#xff09;与模具寿命。传统有限元分析&#xff08;FEA&#xff09;在面对大型复杂模具装配体时&#xff0c;存在网格划分困难、计算资源消耗大、周期长等瓶颈。本文以…

用AI生成的html页面设计放到到Axure上实现再改造的方法

要将 AI 生成的 HTML 原型导入 Axure&#xff0c;该方法的核心逻辑是以 Figma 为 “中间桥梁”&#xff08;因 Axure 无法直接读取 HTML&#xff0c;需通过 Figma 转换格式&#xff09;&#xff0c;分 3 步即可完成&#xff0c;以下是详细操作指南&#xff08;含每步目标、具体…

从入门到实战:Linux sed命令全攻略,文本处理效率翻倍

从入门到实战&#xff1a;Linux sed命令全攻略&#xff0c;文本处理效率翻倍 文章目录从入门到实战&#xff1a;Linux sed命令全攻略&#xff0c;文本处理效率翻倍一、认识sed&#xff1a;什么是流编辑器&#xff1f;二、吃透sed工作原理&#xff1a;为什么它能高效处理文本&am…

TIOBE 8月编程语言榜深度解析:Python占比突破26%,Perl成最大黑马

根据TIOBE最新发布的2025年8月编程语言排行榜&#xff0c;一场静默的技术变革正在上演&#xff1a;Python以26.14%的占比首次突破26%大关&#xff0c;连续12个月稳居榜首。这一数据不仅刷新了Python自身的历史纪录&#xff0c;更成为TIOBE指数自2001年创立以来的最高单语言占比…

从发现到恢复,看瑞数信息如何构建“抗毁重构”实战路径

在信息化社会&#xff0c;“韧性”“弹性”这些词汇常被用来形容系统抵御和应对风险的能力&#xff0c;但对于身处关键基础设施行业的运营者来说&#xff0c;这些概念往往过于抽象&#xff0c;难以直接指导实践。 相比之下&#xff0c;“抗毁重构”更具画面感。它不仅是一个管理…

深入理解 jemalloc:从内存分配机制到技术选型

在高性能服务&#xff08;如数据库、缓存、JVM&#xff09;的底层优化中&#xff0c;内存分配效率直接影响系统整体性能。本文将从操作系统底层的malloc机制切入&#xff0c;详解 jemalloc 的设计理念、开源应用场景、实战案例&#xff0c;技术选型分析 一、操作系统底层的内存…

websoket使用记录

1.项目使用记录1.医疗项目中渲染回收柜温湿度&#xff0c;需要实时更新2.回收柜安瓿回收和余液回收时&#xff0c;需要前端发送指令给回收柜&#xff0c;比如开门、关门等。还需要收到回收柜结果&#xff0c;比如回收的药品信息等。我项目中用的是浏览器自带的websoket&#xf…

DevOps篇之通过GitLab CI 流水线实现k8s集群中helm应用发布

一. 设计思路 构建一个 GitLab CI 流水线&#xff0c;并且要集成到 K8s 集群中的 Helm 应用发布流程。首先&#xff0c;需要了解 GitLab CI 的基本结构&#xff0c;比如.gitlab-ci.yml 文件的配置&#xff0c;包括 stages、jobs、变量设置等。然后&#xff0c;结合之前讨论的 H…

详尽 | Deeplabv3+结构理解

https://arxiv.org/pdf/1802.02611.pdf https://link.springer.com/chapter/10.1007/978-3-319-10578-9_23 目录 Deeplabv3 Encoder部分 Decoder部分 补充摘要 SPP 空间金字塔池化层模块 Dilated/Atrous Conv 空洞卷积 Deeplabv3 deeplab-v3是语义分割网络&#xff0c;组…

【51单片机】【protues仿真】基于51单片机音乐盒(8首歌曲)系统

目录 一、主要功能 二、使用步骤 三、硬件资源 四、软件设计 五、实验现象 一、主要功能 1、数码管显示当前歌曲序号 2、按键切换歌曲和播放暂停​ 3、内置8首音乐 二、使用步骤 基于51单片机的音乐盒是一种能够存储和播放多首歌曲的电子设备&#xff0c;通过定时器产…