개발/TypeORM
[TypeORM] @Many-to-One & @One-to-Many를 활용하여 @Many-to-Many Relations 구현
8시20분
2021. 9. 7. 08:20
TypeORM을 통해 Table간 Relation을 구성하다보면 N : N의 관계로 구성을 해야될 때가 있다.
TypeORM의 공식 문서를 확인해보면 N : N을 구성하는 법은 다음과 같다.
// category.entity.ts
import {Entity, PrimaryGeneratedColumn, Column} from "typeorm";
@Entity()
export class Category {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
}
// question.enetity.ts
import {Entity, PrimaryGeneratedColumn, Column, ManyToMany, JoinTable} from "typeorm";
import {Category} from "./Category";
@Entity()
export class Question {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
text: string;
@ManyToMany(() => Category)
@JoinTable()
categories: Category[];
}
Category 테이블과 Question 테이블이 N : N의 관계로 구성된다.
TypeORM에서 @JoinTable( )을 통해 자동으로 CategoryId와 QuestionId가 칼럼으로 되어있는 테이블을 자동으로 생성해주는데 이 테이블은 services.ts 혹은 controllers.ts가 없고, 테이블만 존재하는 상태이기 때문에 해당 테이블 관련 API를 구축하기 힘들고, TypeORM이 자동으로 생성하다보니 개발자가 직접 테이블을 제어하기 힘들다는 단점이 있다.
이러한 단점을 해결하는 방법으로는 @One-to-many, @Many-to-One을 활용하여 직접 @Many-to-Many와 같은 Relations를 구현하는 방법이 있다.
// category.entity.ts
import {Entity, PrimaryGeneratedColumn, Column, OneToMany} from "typeorm";
@Entity()
export class Category {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
@OneToMany(() => CategoryQuestion, (categoryQuestion) => categoryQuestion.category)
categoryQuestions: CategoryQuestion[];
}
// question.entity.ts
import {Entity, PrimaryGeneratedColumn, Column, OneToMany, JoinTable} from "typeorm";
import {Category} from "./Category";
@Entity()
export class Question {
@PrimaryGeneratedColumn()
id: number;
@Column()
title: string;
@Column()
text: string;
@OneToMany(() => CategoryQuestion, (categoryQuestion) => categoryQuestion.question)
categoryQuestions: CategoryQuestion[];
}
// categoryquestion.entity.ts
import {Entity, PrimaryGeneratedColumn, Column, ManyToOne, JoinTable} from "typeorm";
import {Category} from "./Category";
import {Question} from "./Question";
@Entity()
export class CategoryQuestion {
@PrimaryGeneratedColumn()
id: number;
@Column()
categoryId: number;
@Column()
questionId: number;
@ManyToOne(() => Category, (category) => category)
category: Category;
@ManyToOne(() => Question, (question) => question)
question: Question;
}
위와 같이 entity.ts로 Join Table을 따로 관리할 경우, @JoinTable( )로 생성한 테이블과 달리 categoryQuestion.service.ts로 직접 테이블에 접근이 가능하고, 코드적으로 명확하게 파악할 수 있다.