这章内容参考TypeORM官网Embedded Entity及Entity Listener/Subscriber
Embedded Entity
对于每个Entity都会用的栏位/属性,可以用partial entity的概念,把相关的属性独立出来一个class,增加code reuse。
例如,每个Entity都要建立时间跟上次更新时间
则可以新增EntityDate class如下
@Entity()
export class EntityDate {
@Column({
nullable: true,
})
LastUpdatedDate: Date;
@Column({
nullable: true,
})
createDate: Date;
}
在User、Role及Platform都加入下面这段
@Column(type => EntityDate) // 指定column为EntityDate Entity
entityDate: EntityDate; // 型别为EntityDate
在下面Listener& Subscriber部分测试
Entity Listener
简单来说就是Entity有读取、新增、修改、删除的动作之前或之后可以做一些事情
主要有以下
- @AfterLoad()
- 适用QueryBuilder及Repository find
- @BeforeInsert()/@AfterInsert()
- 仅适用Repository save方法
- @BeforeUpdate()/@AfterUpdate()
- 仅适用Repository save方法,update不行
- @BeforeRemove()/@AfterRemove()
- 仅适用Repository remove方法
大致来看,Listener用在用Repository操作比较多,无法QueryBuilder无法触发Entity Listener。
以Role Entity为例,假设新增或修改Role时,EntityDate属性要更新。
@Entity()
export class Role {
...
@ManyToMany(type => User, user => user.roles)
users: User[];
@Column(type => EntityDate)
entityDate: EntityDate ;
@BeforeInsert()
updateDatesWhenInsert(){
// 新增entity前指定现在时间给下列属性
this.entityDate.createDate = new Date();
this.entityDate.LastUpdatedDate = new Date();
}
@BeforeUpdate()
updateDateWhenUpdate(){
// 更新entity前更新LastUpdatedDate
this.entityDate.LastUpdatedDate = new Date();
}
}
Event Subscriber
Event Listener没办法用在User Entity上,因为User Service已经用Query Builder改写。
如果希望User新增前填入目前时间,新增后加入user权限,根据typeorm官网,可以用Event Subscriber
新增UserSubscriber.ts,注意目录要放在typeormconfig指定的位置
"migrations": [
"src/shared/migration/**/*.ts"
],
"subscribers": [
"src/shared/subscriber/*.ts"
],
可以用typorm cli
typeorm subscriber:create -n UserSubscriber
import { EventSubscriber, EntitySubscriberInterface, InsertEvent } from 'typeorm';
import { User } from 'shared/entity/User';
import { Logger } from '@nestjs/common';
import { Role } from 'shared/entity/Role';
@EventSubscriber()
export class UserSubscriber implements EntitySubscriberInterface<User> {
listenTo(){
return User;
}
async beforeInsert(event: InsertEvent<User>){
Logger.log(`-----Before Insert------`);
Logger.log(event.entity); // 显示insert之前entity的信息
event.entity.entityDate = {
createDate: new Date(),
LastUpdatedDate: new Date(),
};
}
async afterInsert(event: InsertEvent<User>){
Logger.log(`-----After Insert------`);
// 希望在insert user后自动加入user权限
// 使用Subscriber的好处是可以从event取得entity manager物件
// 进而可以使用querybuilder做任何SQL操作
const role = await event.manager.createQueryBuilder(Role, 'r')
.where('r.roleName = :name', {name: 'user'})
.getOne();
// 要加入user使用relationquerybuilder
event.manager.createQueryBuilder(User, 'u')
.relation('roles')
.of(event.entity)
.add(role);
}
}
不指定roleIds,把userService稍微改写以后用Postman测试
推荐一下我的公众号: 【 geekjc 】,微信号: 【 c8706288 】一起学习交流编程知识,分享经验,各种有趣的事。