文章发布在专栏NestJS最佳实践中
代码地址:github.com/slashspaces…
学习方针
- 软删去与康复
- 批量删去与批量康复
什么是软删去
软删去是一种广泛应用于业务应用程序的模式。它允许您将一些记载标记为已删去,而无需从数据库中真正删去。因此,能够在防止软删去的记载被选中的一起,旧记载仍然能够被引用。
经过软删去,咱们能够完成相似于回收站的功用,比如将文章软删去后放进回收站,后面也能够从回收站中康复。
TypeORM软删去及康复用法
-
在Entity中运用
@DeleteDateColumn()
装饰器@DeleteDateColumn() public deletedAt: Date;
-
软删去: 运用
softRemove
替代remove
- 履行
softRemove
后deletedAt
由null
变为具体删去日期
- 履行
-
康复: 运用
restore
办法康复数据- 履行
restore
后deletedAt
由具体删去日期变为null
- 履行
-
查询: 当咱们运用
find()
或相似办法查询时,TypeORM会主动取查询deletedAt
为NULL
的记载,当然咱们也能够指定withDeleted
字段来控制是否查询软删去数据const category = await this.categoriesRepository.findOne(id, { relations: ['posts'], withDeleted: true }
如下图所示, deletedAt
一列为日期代表该条数据被软删去,为null
则为正常数据
批量删去与康复DTO
由于各模块都会用到软删去及康复功用,因此咱们提取出DeleteDto
和 RestoreDto
到 src/common/dtos
目录下,作为大局共用DTO
/**
* 批量删去
*/
export class DeleteDto {
@IsUUID(undefined, { each: true, message: 'ID格局过错' })
@IsDefined({ each: true, message: 'ID有必要指定' })
ids: string[] = [];
// 是否为软删去
@Transform(({ value }) => Boolean(value))
@IsBoolean()
@IsOptional()
soft?: boolean;
}
/**
* 批量康复
*/
export class RestoreDto {
@IsUUID(undefined, { each: true, message: 'ID格局过错' })
@IsDefined({ each: true, message: 'ID有必要指定' })
ids: string[] = [];
}
软删去及数据康复
接下来咱们要完成文章模块的软删去及数据康复
首先给QueryPostDto
加上soft
字段用来判断是否查询软删去数据
@DtoValidation({ groups: ['query'] })
export class QueryPostDto extends PaginationDto {
@IsUUID(undefined, { message: '分类ID格局过错' })
@IsOptional()
category?: string;
@IsEnum(SelectSoftDeleteMode)
@IsOptional()
soft?: SelectSoftDeleteMode;
}
-
@IsEnum
: 校验soft值是否为指定枚举值
接下来修改一下PostService
- DeleteDto中soft为true代表软删去,要履行
softRemove
- DeleteDto中soft不设置或设为false,代表物理删去,要履行
remove
@Injectable()
export class PostService {
// ...
async remove({ ids, soft }: DeleteDto) {
const posts = await this.postsRepository.find({
where: { id: In(ids) },
withDeleted: false, // 过滤掉已删去的
});
if (soft) return this.postsRepository.softRemove(posts);
return this.postsRepository.remove(posts);
}
async restore({ ids }: RestoreDto) {
const posts = await this.postsRepository.find({
where: { id: In(ids) },
withDeleted: true,
});
// 过滤掉不在回收站中的数据
const deletedIds = posts.filter((post) => !isNil(post.deletedAt)).map((post) => post.id);
this.postsRepository.restore(deletedIds);
}
// ...
}
最后修改下PostController
@Controller('post')
export class PostController {
// ...
@Post('delete')
remove(@Body() data: DeleteDto) {
return this.postService.remove(data);
}
@Patch('restore')
restore(@Body() data: RestoreDto) {
return this.postService.restore(data);
}
// ...
}
这样咱们就完成了文章的批量删去,软删去与批量康复功用啦.至于分类和评论模块的软删去与康复,代码与文章模块相似, 只不过要注意下树形结构的级联操作,这里就不再赘述。