Nest 集成 TypeORM

TypeORM 基础回顾

  • DataSource 配置:包含数据库连接的详细信息,如用户名、密码、驱动、连接池等。
  • Entity 映射:利用装饰器(如 @Entity, @PrimaryGeneratedColumn, @Column)定义数据库表结构。
  • 关系映射:通过 @OneToOne, @OneToMany, @ManyToMany 等装饰器定义表间关系。
  • 初始化与操作:DataSource.initialize 建立连接和表,EntityManager 负责实体的 CRUD 操作。

nest 结合 typeorm

初始化环境

创建 Nest 项目:

bash 复制代码
nest new nest-typeorm -p npm

然后创建一个 crud 的模块:

bash 复制代码
nest g resource user

引入 mysql、typeorm:

bash 复制代码
npm install @nestjs/typeorm typeorm mysql2

@nestjs/typeorm 就是把 typeorm api 封装了一层。

引入动态模块 TypeOrmModule,使用 forRoot 方法进行全局注册,只需配置一次即可在任何地方使用,TypeOrmModule 是全局模块,这样就无需在每个模块中重复导入:

typescript 复制代码
import { Module } from '@nestjs/common';
import { TypeOrmModule } from '@nestjs/typeorm';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { User } from './user/entities/user.entity';
import { UserModule } from './user/user.module';

@Module({
  imports: [
    UserModule,
    TypeOrmModule.forRoot({
      type: 'mysql',
      host: 'localhost',
      port: 3306,
      username: 'root',
      password: 'xxx',
      database: 'typeorm_test',
      synchronize: true,
      logging: true,
      entities: [User],
      poolSize: 10,
      connectorPackage: 'mysql2',
      extra: {
        authPlugin: 'sha256_password',
      },
    }),
  ],
  controllers: [AppController],
  providers: [AppService],
})
export class AppModule {}

然后在 User 的 Entity 里加一些映射的信息:

typescript 复制代码
import { Column, Entity, PrimaryGeneratedColumn } from 'typeorm';

@Entity({
  name: 'nest_user',
})
export class User {
  @PrimaryGeneratedColumn()
  id: number;

  @Column({
    name: 'nest_name',
    length: 50,
  })
  name: string;
}

给映射的表给个名字叫 nest_user,然后有两个数据库列,分别是 id 和 nest_name。

运行:

bash 复制代码
npm run start:dev

在 workbench 看下:

CRUD 操作

然后是增删改查,我们可以注入 EntityManager 来做:

typescript 复制代码
import { Injectable } from '@nestjs/common';
import { InjectEntityManager } from '@nestjs/typeorm';
import { EntityManager } from 'typeorm';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { User } from './entities/user.entity';

@Injectable()
export class UserService {
  @InjectEntityManager()
  private manager: EntityManager;

  create(createUserDto: CreateUserDto) {
    this.manager.save(User, createUserDto);
  }

  findAll() {
    return this.manager.find(User);
  }

  findOne(id: number) {
    return this.manager.findOne(User, {
      where: { id },
    });
  }

  update(id: number, updateUserDto: UpdateUserDto) {
    this.manager.save(User, {
      id: id,
      ...updateUserDto,
    });
  }

  remove(id: number) {
    this.manager.delete(User, id);
  }
}

UserController 代码如下:

typescript 复制代码
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);
  }
}

我们使用 postman 发送 post 请求携带数据测试一下:

再试试查询:

全部查询:

单个查询:

再就是修改:

试试删除:

至此,我们就正式打通了从请求到数据库的整个流程!

使用 Repository 简化数据操作

我们上面是通过 @InjectEntityManager 来注入的 entityManager 对象。

直接用 EntityManager 的缺点是每个 api 都要带上对应的 Entity:

可以先 getRepository(User) 拿到 user 对应的 Repository 对象,再调用这些方法。

若需要使用特定实体的 Repository,可以通过 forFeature 方法将实体注入对应模块,便于进行 CRUD 操作:

它有的方法和 EntityManager 一样,只能用来操作当前 Entity。

还可以注入 DataSource:

不过这个不常用。

这就是 Nest 里集成 TypeOrm 的方式。

相关推荐
liangshanbo12153 小时前
前端高级面试题:WebSocket 双向流式通信怎么设计?
前端·websocket·网络协议
可乐鸡翅yeah_3 小时前
新手梳理:HLS 线上问题,哪些该提给 CDN,哪些该找后端切片服务
开发语言·前端·javascript·vue.js·网络协议·http·m3u8在线
zwd20053 小时前
Manim arrange 和 arrange_in_grid 用法详解:buff、aligned_edge、rows/cols(0.21.0 实测)
前端·python·edge
小小龙学IT4 小时前
Go 语言 reflect 反射包深度解析:从 Type/Value 到三大定律与工业实践
前端·golang
小溪学编程4 小时前
C语言篇:枚举类型
java·c语言·前端
xingpanvip4 小时前
星盘接口开发文档:推算星座接口指南
前端·php
Da Da 泓4 小时前
HTML浅浅入门
前端·html
এ慕ོ冬℘゜4 小时前
es6基础
前端·javascript·es6
熊猫钓鱼>_>4 小时前
从2D平铺到3D沉浸:我用HarmonyOS 7端侧AI做了一个全程数据不出设备的空间化私密相册
前端·人工智能·3d·华为·华为云·harmonyos·鸿蒙
大圣编蚕4 小时前
Spring AOP 失效排查:从原理到实战的完整指南
java·后端·spring