NestJS中如何仅通过userId创建Article与User的关联?
优化方案:无需查询User实体,仅用userId创建Article关联
下面提供两种可行的优化方式,均能避免多余的User数据库查询:
方案一:利用TypeORM的getReference创建关联代理对象
TypeORM的getReference方法可以生成一个仅包含id的User代理对象,不会触发数据库查询,但能正确完成与Article的关联映射。
修改服务层代码
async create(createArticleDto: CreateArticleDto) { // 创建User代理对象,仅传入userId即可,无需查询数据库 const user = this.userRepository.getReference(createArticleDto.userId); // 构建Article实例并关联User代理 const article = { ...createArticleDto, user, } as Article; const result = await this.articleRepository.save(article); return result; }
控制器层简化
不需要手动构造空User对象,直接传递DTO即可:
const result = await this.articleService.create(createArticleDto);
方案二:在Article实体中显式添加userId字段
如果更倾向于直接操作外键列,可以在Article实体中新增userId字段,跳过user关联属性的中间处理。
1. 更新Article实体
export class Article { id?: string; // ... 其他业务字段 userId?: string; // 新增userId字段,对应外键列 user?: User; // 保留关联关系,不影响后续查询关联数据 }
2. 修改ArticleSchema
在columns中添加userId的定义:
export const ArticleSchema = new EntitySchema<Article>({ name: 'Article', target: Article, tableName: 'Article', columns: { id: { type: String, primary: true, generated: 'uuid', }, // ... 其他字段 userId: { type: String, nullable: false, }, }, relations: { user: { type: 'many-to-one', target: 'User', nullable: false, joinColumn: { name: 'userId', referencedColumnName: 'id', }, }, }, });
3. 服务层代码简化
直接给userId赋值,无需处理user属性:
async create(createArticleDto: CreateArticleDto) { const article = { ...createArticleDto, } as Article; const result = await this.articleRepository.save(article); return result; }
选择建议
- 方案一适合需要保留
user关联属性、后续可能要直接操作关联User实例的场景; - 方案二更直接高效,适合仅需完成外键关联、不需要额外操作User实例的场景;
- 两种方案均能完全避免原代码中多余的
userService.getById查询,提升接口性能。
内容的提问来源于stack exchange,提问作者Thiago Dias
相关产品推荐
相关产品推荐

