TypeORM 对将两个表映射在一起的表进行 COUNT 查询

Posted

技术标签:

【中文标题】TypeORM 对将两个表映射在一起的表进行 COUNT 查询【英文标题】:TypeORM make COUNT query on table which maps two tables together 【发布时间】:2021-01-27 21:44:43 【问题描述】:

我有两个实体ModelVideo,其中Video 基本上存储有关视频的信息,Model 存储有关模型的信息。因为每个视频可以有多个模型,每个模型可以有多个视频实体,看起来像这样:

我的实体和表格的样子:

// Video Entity
@Entity()
export class Video 
  @PrimaryGeneratedColumn()
  id?: number; 

  @Column( charset: 'utf8mb4', collation: 'utf8mb4_unicode_ci' )
  name: string;

  @Column( type: 'text', charset: 'utf8mb4', collation: 'utf8mb4_unicode_ci' )
  description: string;

  @ManyToMany((type) => Model)
  @JoinTable()
  models: Model[];



// Model Entity
@Entity()
export class Model 

  @PrimaryGeneratedColumn()
  id?: number; 

  @Column()
  name: string;

  @Column()
  code: string;

因为模型和视频之间存在关系@ManyToMany,TypeORM 还创建了一个额外的表来连接这两者。表名是video_models_model,它看起来像这样:

+-----------+---------+
| videoId   | modelId |
+===========+=========+
| 1         | 107     |
+-----------+---------+
| 2         | 142     |
+-----------+---------+
| 3         | 91      |
+-----------+---------+

我需要什么:

根据 modelId,我需要找出 COUNT() 的视频。 在常规查询语言中,它会是这样的:

SELECT model.*, COUNT(model_videos.videoId) as totalVideos FROM model as model
LEFT JOIN `video_models_model` `model_videos` ON `model_videos`.`modelId`=`model`.`id` 
WHERE model.id = 1;

我尝试了什么:

这就是常规查询的样子:
this.modelRepository
  .createQueryBuilder('model')  
  .where('model.id = :id',  id: id )        
  .getOne();

所以我所做的被添加到Model实体

  @ManyToMany(type => Video)
  @JoinTable()
  videos: Video[];

然后我尝试了

this.modelRepository
  .createQueryBuilder('model')
  .leftJoin('model.videos', 'videos')
  .select('COUNT(videos)', 'totalVideos')  
  .where('model.id = :id',  id: id )        
  .getOne();

但它对我根本不起作用,它创建了一个名为model_videos_video 的附加表,其中包含modelIdvideoId 列。所以基本上重复video_models_model表。

有什么方法可以使用 TypeORM 进行简单的查询?

【问题讨论】:

【参考方案1】:

我发现我必须更改我的实体以使其具有双向性,因此: 视频实体:

@Entity()
export class Video 
  @PrimaryGeneratedColumn()
  id?: number; 

  @Column( charset: 'utf8mb4', collation: 'utf8mb4_unicode_ci' )
  name: string;

  @Column( type: 'text', charset: 'utf8mb4', collation: 'utf8mb4_unicode_ci' )
  description: string;

  @ManyToMany(type => Model, model => model.videos)
  @JoinTable()
  models: Model[];

模型实体:

@Entity()
export class Model 

  @PrimaryGeneratedColumn()
  id?: number; 

  @Column()
  name: string;

  @Column()
  code: string;

  @ManyToMany(type => Video, video => video.models)
  videos: Video[];

然后我这样查询:

this.modelRepository
  .createQueryBuilder('model')
  .loadRelationCountAndMap('model.videoCount', 'model.videos')
  .where('model.id = :id',  id: id )        
  .getOne();

【讨论】:

以上是关于TypeORM 对将两个表映射在一起的表进行 COUNT 查询的主要内容,如果未能解决你的问题,请参考以下文章

如何在 TypeORM 中使用具有自动递增 id 列的表进行级联插入

将两个不同的表组合在一起进行查询

如何使用 typeorm nestjs 加入 3 个关系表

TypeORM 无关联关系的mysql多表连接查询

MyBatis之基于XML的表之间映射

typeorm中最简单的事务使用typeorm系列