TypeORM Many to Many

00_8_3·2021년 2월 5일
1

TypeORM Many to Many

위의 ERD와 같은 다대다 테이블을 만들어 보겠다.

@JoinColumn()을 이용한 다대다

user.entity.ts

import { ApiProperty } from '@nestjs/swagger';
import {
  Entity,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  PrimaryGeneratedColumn,
  OneToMany,
  Unique,
  Check,
  ManyToMany,
  JoinTable,
  OneToOne,
} from 'typeorm';

import { Post } from '../../posts/entity/post.entity';
import { UserProfile } from './user-profile.entity';
import { PostComment } from 'src/posts/entity/post-comment.entity';
import { Favorite } from './user-favorite.entity';

@Entity()
@Unique(['email'])
export class User {
  /** Columns */

  @PrimaryGeneratedColumn('uuid')
  readonly id: string;
  
  @OneToMany((type) => Favorite, (favorites) => favorites.user)
  favorites!: Favorite[];
}

post.entity.ts

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  UpdateDateColumn,
  CreateDateColumn,
  JoinColumn,
  ManyToOne,
  OneToOne,
  OneToMany,
  ManyToMany,
  JoinTable,
} from 'typeorm';
import { IsString, IsUUID } from 'class-validator';
import { User } from '../../users/entity/user.entity';
import { PostInformation } from './post-information.entity';
import { PostMetadata } from './post-metadata.entity';
import { Tag } from 'src/tags/entity/tag.entity';
import { PostComment } from './post-comment.entity';
import { Favorite } from 'src/users/entity/user-favorite.entity';

@Entity()
export class Post {

  @PrimaryGeneratedColumn('uuid')
  readonly id: string;

  @OneToMany((type) => Favorite, (favorites) => favorites.post)
  favorites!: Favorite[];
}

favorite.entity.ts

import { IsUUID } from 'class-validator';
import {
  Column,
  Entity,
  JoinColumn,
  ManyToOne,
  PrimaryGeneratedColumn,
} from 'typeorm';
import { User } from './user.entity';
import { Post } from 'src/posts/entity/post.entity';

@Entity()
export class Favorite {
  @PrimaryGeneratedColumn('uuid')
  readonly id: string;

  @Column('uuid')
  @IsUUID('4')
  user_id!: string;

  @Column('uuid')
  @IsUUID('4')
  post_id!: string;

  @ManyToOne(() => User, (user) => user.favorites)
  @JoinColumn({ name: 'user_id' })
  user!: User;

  @ManyToOne(() => Post, (post) => post.favorites)
  @JoinColumn({ name: 'post_id' })
  post!: Post;
}

모든 테이블에 1:다 관계로 @JoinColumn을 통해 직접 만들었지만 TypeORM의 @JoinTable을 사용해 조금더 편하게 만들어 보겠다.

@JoinTable()을 이용한 다대다

user.entity.ts

import { ApiProperty } from '@nestjs/swagger';
import {
  Entity,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  PrimaryGeneratedColumn,
  OneToMany,
  Unique,
  Check,
  ManyToMany,
  JoinTable,
  OneToOne,
} from 'typeorm';

import { Post } from '../../posts/entity/post.entity';
import { UserProfile } from './user-profile.entity';
import { PostComment } from 'src/posts/entity/post-comment.entity';
import { Favorite } from './user-favorite.entity';

@Entity()
@Unique(['email'])
export class User {
  /** Columns */

  @PrimaryGeneratedColumn('uuid')
  readonly id: string;
  
  @ManytoMany((type) => Favorite, (favorites) => favorites.user)
  favorites!: Favorite[];
}

post.entity.ts

import {
  Entity,
  PrimaryGeneratedColumn,
  Column,
  UpdateDateColumn,
  CreateDateColumn,
  JoinColumn,
  ManyToOne,
  OneToOne,
  OneToMany,
  ManyToMany,
  JoinTable,
} from 'typeorm';
import { IsString, IsUUID } from 'class-validator';
import { User } from '../../users/entity/user.entity';
import { PostInformation } from './post-information.entity';
import { PostMetadata } from './post-metadata.entity';
import { Tag } from 'src/tags/entity/tag.entity';
import { PostComment } from './post-comment.entity';
import { Favorite } from 'src/users/entity/user-favorite.entity';

@Entity()
export class Post {

  @PrimaryGeneratedColumn('uuid')
  readonly id: string;

  @ManyToMany((type) => Favorite, (favorites) => favorites.post)
  @JoinTable({
  	name: "favorite", 
    // 지정안해주면 post_favorites_user 기본값으로 만들어진다.
    	joinColumns:[{name: "post_id"}],
    	inverseJoinColumns:[{name: "user_id"}]
  })
  favorites!: Favorite[];
}
  • @ManyToMany()는 테이블 모두 명시해주거나 하나만 해줘도 된다.
  • @JoinTable()은 둘 중 하나의 테이블에 꼭 명시해줘야 한다.

@JoinCoulmns를 사용하면 따로 Join 테이블을 만들지 않아도 자동으로 만들어준다. 자동으로 만들어 질때 name에 명시를 해주면 이름을 지정 할 수 있다.

공통 옵션

JoinColumn / JoinTable 공통 옵션으로

  • eager 옵션은 N+1 문제를 제어 할 수 있다.
  • cascade or onDelete 옵션은 관계가 연결되어 있는 객체를 추가/수정/삭제되도록 할 수 있다.

0개의 댓글