安装 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 module 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<UserEntity>
) {}
findAll(): Promise<UserEntity[]> {
return this.userRepository.find()
}
findOne(id: string): Promise<UserEntity> {
return this.userRepository.findOne(id)
}
async remove(id: string): Promise<void> {
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<UserEntity> {
return this.userService.create(createUserDto)
}
@Get()
findAll(): Promise<UserEntity[]> {
return this.userService.findAll()
}
@Get(':id')
findOne(@Param('id') id: string): Promise<UserEntity> {
return this.userService.findOne(id)
}
@Delete(':id')
remove(@Param('id') id: string): Promise<void> {
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<UserEntity> {
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