Nest.js 中的数据库操作
安装 Typeorm
为了与 SQL
和 NoSQL
数据库集成, Nest.js
提供了 @nestjs/typeorm
软件包。 Nest.js
使用 TypeORM
,因为它是 TypeScript
最成熟的对象关系映射器( ORM
)。由于它是用 TypeScript
编写的,因此可以与 Nest.js
框架很好地集成。
要开始使用它,先安装所需的依赖项:
npm install --save @nestjs/typeorm typeorm mysql2
本文数据库环境是 MySQL 8
下进行测试,依赖安装完成后在 AppModule(app.module.ts)
添加 TypeOrmModule
配置并且注入整个项目支持:
import { Module } from '@nestjs/common' import { Connection } from 'typeorm' import { TypeOrmModule } from '@nestjs/typeorm' import { AppController } from './app.controller' import { AppService } from './app.service' @Module({ imports: [ TypeOrmModule.forRoot({ type: 'mysql', host: 'localhost', port: 3306, username: 'root', password: '12345678', database: 'nest-demo1', entities: ['dist/**/*.entity.js'], synchronize: true }) ], controllers: [AppController], providers: [AppService] }) export class AppModule { constructor(private connection: Connection) {} }
存储库模式
TypeORM支持存储库设计模式,每个实体都有自己的存储库。这些存储库可以从数据库连接中获取。例如创建一个 user
实体:
nest g controller user
生成 user
文件夹后,新建个 user.entity.ts
实体:
import { Entity, Column, PrimaryColumn, BeforeInsert, CreateDateColumn, UpdateDateColumn } from 'typeorm' import { v4 as uuidV4 } from 'uuid' @Entity('app_user') export class UserEntity { @PrimaryColumn({ type: 'varchar', length: 36, nullable: false, comment: '用户编号' }) id: string @BeforeInsert() updateId(): void { this.id = uuidV4() } @Column({ type: 'varchar', length: 50, unique: true, comment: '用户名' }) username: string @Column({ type: 'varchar', length: 200, comment: '密码' }) password: string @Column({ type: 'varchar', length: 320, unique: true, comment: '邮箱' }) email: string @Column({ comment: '昵称' }) nickname: string @Column({ default: true, comment: '用户状态' }) isActive: boolean @CreateDateColumn({ type: 'timestamp', name: 'created_time', default: () => 'CURRENT_TIMESTAMP(6)', comment: '创建时间' }) createdTime: Date @UpdateDateColumn({ type: 'timestamp', name: 'updated_time', default: () => 'CURRENT_TIMESTAMP(6)', onUpdate: 'CURRENT_TIMESTAMP(6)', comment: '更新时间' }) updatedTime: Date }
上面涉及到各种名词请参考: TypeOrm文档 ,上面配置文件有个字段 entities: ['dist/**/*.entity.js']
项目涉及所有的实体类命名风格都是这样,这样一来程序启动就会注册自己的实体。然后在 UsersModule
注册指定的实体类 user.module.ts
:
import { Module } from '@nestjs/common' import { TypeOrmModule } from '@nestjs/typeorm' import { UserController } from './user.controller' import { UserService } from './user.service' import { UserEntity } from './user.entity' @Module({ imports: [TypeOrmModule.forFeature([UserEntity])], controllers: [UserController], providers: [UserService] }) export class UserModule {}
然后下面进行编写 user
业务,打开 user.service.ts
:
import { Injectable } from '@nestjs/common' import { InjectRepository } from '@nestjs/typeorm' import { Repository } from 'typeorm' import { UserEntity } from './user.entity' @Injectable() export class UserService { constructor( @InjectRepository(UserEntity) private userRepository: Repository ) {} findAll(): Promise { return this.userRepository.find() } findOne(id: string): Promise { return this.userRepository.findOne(id) } async remove(id: string): Promise { await this.userRepository.delete(id) } }
创建好之后,下面进行编写控制器的路由来访问 user.controller.ts
:
import { Controller, Get, Post, Delete, Body, Param } from '@nestjs/common' import { CreateUserDto } from './dto/create-user.dto' import { UserEntity } from './user.entity' import { UserService } from './user.service' @Controller('user') export class UserController { constructor(private readonly userService: UserService) {} @Post() create(@Body() createUserDto: CreateUserDto): Promise { return this.userService.create(createUserDto) } @Get() findAll(): Promise { return this.userService.findAll() } @Get(':id') findOne(@Param('id') id: string): Promise { return this.userService.findOne(id) } @Delete(':id') remove(@Param('id') id: string): Promise { return this.userService.remove(id) } }
上面除了创建,其他都很好理解,都是根据 Orm
方法执行对应的方法,创建用户需要用到 DTO (Data Transfer Object)
创建的简单类模式来创建需要的对象,在 user
文件夹下新建个 dto
文件夹,创建 create-user.dto.ts
:
import { IsNotEmpty } from 'class-validator' export class CreateUserDto { @IsNotEmpty() readonly username: string @IsNotEmpty() readonly password: string @IsNotEmpty() readonly email: string @IsNotEmpty() readonly nickname: string }
创建好之后在 user.service.ts
添加 create()
方法:
create(createUserDto: CreateUserDto): Promise { const user = new UserEntity() user.username = createUserDto.username user.password = createUserDto.password user.email = createUserDto.email user.nickname = createUserDto.nickname return this.userRepository.save(user) }
class-validator
是实用的数据验证工具: npm i class-validator
结语
上述代码数据库使用就是这样,不过细节上还有很多问题,比如新增用户要注意用户名的重复,删除需要验证等,这些后续再慢慢完善。
本文案例源码: nest.js-typeorm-demo-1