当前位置: 首页 > news >正文

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.xdnf.cn/news/1422793.html

相关文章:

  • 【C++进阶篇】学习C++就看这篇--->多态超详解
  • 传统web项目,vue开发实践篇01
  • 微服务Docker-compose之若依部署
  • 视频提取文字用什么软件好?分享6款免费的视频转文字软件!
  • apipost 8.x 脚本循环调用接口
  • 云手机为什么会受到广泛关注?
  • 单链表的基本原理与实现
  • 深入掌握 Flask 配置管理:从基础到高级实战
  • uniapp使用uview UI,自定义级联选择组件
  • 六、练习3:Gitee平台操作
  • RSA的CTF题目环境和做题复现第1集
  • shell——函数与数组
  • 华东制造企业推荐的SD-WAN服务商排名
  • java中常见的几种排序算法
  • 毕业设计:丹麦电力电价预测预测未来24小时的电价pytorch+lstm+历史特征和价格+时间序列 电价预测模型资源 完整代码数据可直接运行
  • js脚本和ts脚本相互调用
  • 虚拟机一插SD卡就蓝屏,导致整个电脑系统蓝屏怎么办
  • 一、SVN与svnbucket.com常见问题解答
  • PTP高精度时间同步的核心:E2E与P2P延迟补偿机制
  • FPGA|Quartus II 中pll IP核的具体使用方法
  • 优化正则表达式性能:预编译与模式匹配的最佳实践
  • Coolutils Total PDF Converter中文版:多功能PDF文件转换器
  • 奇偶破题:当反函数撞上奇函数
  • 【前端:Html】--4.进阶:媒体
  • 【论文阅读】Sparse4D v3:Advancing End-to-End 3D Detection and Tracking
  • 订单后台管理系统-day07菜品模块
  • MIT 6.5840 (Spring, 2024) 通关指南——Lab 2: Key/Value Server
  • openssh 安装部署
  • 【Day 41】Shell脚本-循环
  • 802.11 和 802.1X