You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在NestJS+TypeORM中用关联表实现Item的可选Scale属性

实现方案(NestJS + TypeORM + PostgreSQL)

1. 定义Scale枚举

先创建TypeScript枚举,用枚举键作为scale_id存储值,枚举值作为显示用的名称:

// src/enums/scale.enum.ts
export enum Scale {
  SCALE_1 = '小型',
  SCALE_2 = '中型',
  SCALE_3 = '大型',
  SCALE_4 = '超大'
}

2. 创建ItemScale实体(对应item_scale表)

这个关联表存储Item与Scale的映射关系,设置联合主键并限制item_id唯一(确保一个Item最多对应一个Scale):

// src/entities/item-scale.entity.ts
import { Entity, PrimaryColumn, ManyToOne, JoinColumn } from 'typeorm';
import { Item } from './item.entity';
import { Scale } from '../enums/scale.enum';

@Entity('item_scale')
export class ItemScale {
  @PrimaryColumn({ type: 'enum', enum: Scale })
  scale_id: Scale;

  @PrimaryColumn({ unique: true })
  item_id: number;

  @ManyToOne(() => Item, (item) => item.scale, { onDelete: 'CASCADE' })
  @JoinColumn({ name: 'item_id' })
  item: Item;
}

3. 修改Item实体,关联ItemScale

在Item实体中添加一对一关联,标记为可选(nullable: true):

// src/entities/item.entity.ts
import { Entity, PrimaryGeneratedColumn, Column, OneToOne, JoinColumn } from 'typeorm';
import { ItemScale } from './item-scale.entity';

@Entity('item')
export class Item {
  @PrimaryGeneratedColumn()
  id: number;

  // 你的现有属性
  @Column()
  name: string;
  // ... 其他属性

  @OneToOne(() => ItemScale, (itemScale) => itemScale.item, { nullable: true, cascade: true })
  @JoinColumn({ name: 'id', referencedColumnName: 'item_id' })
  scale: ItemScale;
}

cascade: true可实现保存Item时自动同步关联的ItemScale数据。

4. 实现核心功能

4.1 通过scale_id查询Item

在Service层使用QueryBuilder关联查询:

// src/item/item.service.ts
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { Item } from '../entities/item.entity';
import { Scale } from '../enums/scale.enum';

@Injectable()
export class ItemService {
  constructor(
    @InjectRepository(Item)
    private itemRepository: Repository<Item>,
  ) {}

  async getItemsByScale(scaleId: Scale): Promise<Item[]> {
    return this.itemRepository
      .createQueryBuilder('item')
      .innerJoinAndSelect('item.scale', 'itemScale')
      .where('itemScale.scale_id = :scaleId', { scaleId })
      .getMany();
  }
}

4.2 获取Scale名称

通过枚举直接映射存储的scale_id到显示名称:

// 示例:获取单个Item的Scale名称
const item = await this.itemRepository.findOne({ 
  where: { id: 1 }, 
  relations: ['scale'] 
});
const scaleName = item.scale ? Scale[item.scale.scale_id] : null;

5. 数据库枚举初始化(可选)

如果使用TypeORM自动同步(仅开发环境开启synchronize: true),会自动创建PostgreSQL枚举类型。若手动初始化,执行以下SQL:

CREATE TYPE scale_enum AS ENUM ('SCALE_1', 'SCALE_2', 'SCALE_3', 'SCALE_4');

内容的提问来源于stack exchange,提问作者sharf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 06:35:01