Nest 操作数据库
一、主流 ORM 框架之 TypeORM
# 安装依赖
pnpm add -S typeorm pg @nestjs/typeorm
// app.module.ts
import { Module } from '@nestjs/common';
import { AppController } from './app.controller';
import { AppService } from './app.service';
import { UserModule } from './user/user.module';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './user/entities/user.entity';
@Module({
imports: [
// 初始化数据库
TypeOrmModule.forRoot({
type: 'postgres',
host: 'localhost',
port: 5432,
username: 'postgres',
password: 'root',
database: 'db1118',
entities: [User],
synchronize: true, // 生产环境应该关闭自动更新数据库功能,采用手动迁移的方式来管理数据库
logging: true,
}),
UserModule,
],
controllers: [AppController],
providers: [AppService],
})
export class AppModule {}
// user\entities\user.entity.ts
import { Entity, PrimaryGeneratedColumn, Column } from 'typeorm';
@Entity()
export class User {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@Column()
sex: string;
@Column()
createTime: Date;
@Column()
updateTime: Date;
}
1.1 实现增删查改
1.1.1 实体管理器(EntityManager)
// user.service.ts
import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { InjectEntityManager } from '@nestjs/typeorm';
import { EntityManager } from 'typeorm';
import { User } from './entities/user.entity';
@Injectable()
export class UserService {
// 使用 InjectEntityManager 装饰器注入了 EntityManager 实体管理器,来调用他的 API 进行增删查改操作。
// 每次操作都要指定要处理的实体类,例如这里的User
@InjectEntityManager()
private manage: EntityManager;
async create(createUserDto: CreateUserDto) {
await this.manage.save(User, createUserDto);
}
async findAll() {
return await this.manage.find(User);
}
async findOne(id: number) {
return this.manage.findBy(User, { id });
}
async update(id: number, updateUserDto: UpdateUserDto) {
return await this.manage.save(User, {
id,
...updateUserDto,
});
}
async remove(id: number) {
return await this.manage.delete(User, { id });
}
}
1.1.2 存储库(Repository)
Repository 对象拥有与 EntityManager 同样的功能,区别在于:
- 使用
Repository时不需要每次操作都传入实体对象 - 由于
Nest的依赖注入作用域限定在模块级别,因此需要在Module中通过forFeature方法导入并注册这些存储库。
代码如下:
// user.service.ts
import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';
@Injectable()
export class UserService {
@InjectRepository(User)
private userRepository: Repository<User>;
async create(createUserDto: CreateUserDto) {
createUserDto.createTime = createUserDto.updateTime = new Date();
await this.userRepository.save(createUserDto);
}
async findAll() {
return await this.userRepository.find();
}
async findOne(id: number) {
return this.userRepository.findBy({ id });
}
async update(id: number, updateUserDto: UpdateUserDto) {
updateUserDto.updateTime = new Date();
return await this.userRepository.update(id, updateUserDto);
}
async remove(id: number) {
return await this.userRepository.delete(id);
}
}
// user.module.ts
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './entities/user.entity';
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}
1.1.3 查询构建器(QueryBuilder)
QueryBuilder 是 TypeOrm 中最强大的功能之一,它提供了更加底层的数据库查询操作,具有灵活度高,支持组合更复杂的 SQL 查询语句。
import { Injectable } from '@nestjs/common';
import { CreateUserDto } from './dto/create-user.dto';
import { UpdateUserDto } from './dto/update-user.dto';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { User } from './entities/user.entity';
@Injectable()
export class UserService {
@InjectRepository(User)
private userRepository: Repository<User>;
async create(createUserDto: CreateUserDto) {
createUserDto.createTime = createUserDto.updateTime = new Date();
await this.userRepository
.createQueryBuilder('u')
.insert()
.into(User)
.values(createUserDto)
.execute();
}
async findAll() {
return await this.userRepository.createQueryBuilder('u').getMany();
}
async findOne(id: number) {
return await this.userRepository
.createQueryBuilder('u')
.where('u.id = :id', { id })
.getOne();
}
async update(id: number, updateUserDto: UpdateUserDto) {
updateUserDto.updateTime = new Date();
return await this.userRepository
.createQueryBuilder('u')
.update(User)
.set(updateUserDto)
.where('u.id = :id', { id })
.execute();
}
async remove(id: number) {
return await this.userRepository
.createQueryBuilder('u')
.delete()
.from(User)
.where('id = :id', { id })
.execute();
}
}
// user.module.ts
import { Module } from '@nestjs/common';
import { UserService } from './user.service';
import { UserController } from './user.controller';
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from './entities/user.entity';
@Module({
imports: [TypeOrmModule.forFeature([User])],
controllers: [UserController],
providers: [UserService],
})
export class UserModule {}
1.1.4 请求示例
@protocol = http://
@hostname = localhost
@port = 3000
@BASE_URL = {{protocol}}{{hostname}}:{{port}}/user
@createdAt = {{$datetime iso8601}}
### 创建用户
POST {{BASE_URL}}/
Content-Type: application/json
{
"name": "women",
"sex": "女",
"createTime": "{{createdAt}}",
"updateTime": "{{createdAt}}"
}
### 查询所有用户
GET {{BASE_URL}}/ HTTP/1.1
### 查询指定用户
GET {{BASE_URL}}/5
### 修改用户
PATCH {{BASE_URL}}/5
Content-Type: application/json
{
"name": "张三"
}
### 删除指定用户
DELETE {{BASE_URL}}/4