JoinTable 삭제 with TypeOrm

00_8_3·2021년 4월 11일
0

JoinTable, 다대다 관계

현재 NestJS로 진행하고 있는 토이프로젝트에서

태그 기능을 추가하기 위해
Post 테이블과 Tag 테이블을 Joinpost_tag테이블을 만들었다.

JoinTable의 자동생성

TypeORM에서는 ManyToMany로 관계를 정의 했을 때
조인테이블이 자동으로 생성된다

post_tag <<< 임의로 이름을 명시하지 않는 경우 조인 되는 테이블이름이 섞여 생성된다. post + _ + tag

joinTable({
name: "post_tag" <<<이렇게 자동생성되는 조인테이블 이름을 임의로 명시 할 수 있다.
})

조인테이블을 이용한 Post에 태그를 추가하는것 까지는 쉽게 진행 되었는데

게시글을 수정을 할 때 게시글에 연결되어있는 태그를 삭제해야 했는데
tag_id를 이용해

  • 조인테이블의 row만 삭제하고

  • post테이블의 tags 속성만 삭제(테이블 row 전체 삭제x)

  • tag테이블의 posts 속성만 삭제(마찬가지로 테이블 row 전체 삭제 x)

    다음과 같이 결과가 나와야했다.

    JoinTable만 삭제?

내가 구글링을 잘 못해인지..TypeORM 문서를 봐도 잘 설명이 안돼어있어 헤멨는데 겨우겨우 찾았다.

tag.service.tsdeleteTag 메서드


  async deleteTag(
    postId: string,
    tagId: string,
  ): Promise<void> {
    
    await getConnection()
      .createQueryBuilder()
      .delete()
      .from('post_tag')
      .where('postId = :postId AND tagId = :tagId', {
        postId: postId,
        tagId: tagId,
      })
      .execute();
  }

TypeORM의 QueryBuilder를 이용하여 자동생성된 joinTable post_tag에 접근이 가능했다.

자동생성테이블 또는 queryBuilder를 사용하지 못한다면?

다대다 관계를 정의함에 있어서
TypeORM 에서는 두 가지 방법이 있다.

  • ManyToMany (다대다)
  • ManyToOne, OneToMany(다대일, 일대다)
    나는 다대다관계를 통해 자동생성된 조인테이블에 접근하여 삭제를 했는데
    만약 이걸 못찾았다면 두 번째방법을 통해 진행 할 수도 있다.

커스텀 다대다 관계 테이블 구성

두 번째방법은 모든 테이블을 직접 명시해주는 것인데
post post_tag tag 엔티티 파일을 직접 만들어 주는 것이다.

  • Post 엔티티
@Entity()
export class Post{
	
  @OneToMany(() => Post_tag, (tags) => tags.post)
  tags: Post_tag[];
}

  • Tag 엔티티
@Entity()
export class Tag{
	
  @OneToMany(() => Post_tag, (posts) => posts.tag )
  posts: Post_tag[];
}
  • 커스텀 조인테이블, Post_tag 엔티티
@Entity()
export class Post_tag {
  
  @Column("uuid")
  post_id!: string;

  @Column("uuid")
  tag_id!: string;

  @ManyToOne(()=>Post, (post) => post.tags)
  post!: Post;
  
  @ManyToOne( () => Tag, (tag) => tag.posts)
  tag!: Tag;

}

위 와 같은 커스텀 엔티티 구성을 통해 직접 Post_tag엔티티를 삭제 할 수있다.

const post_tag = await this.postTagRepository.softRemove({ 
	post_id: postId, tag_id: tagId 
})

delete는 특정 속성 값으로 엔티티 전체를 삭제
remove 엔티티를 값으로 특정 엔티티 삭제
softRemovesoftDelete는 엔티티의 cascadetrue일 경우 부모가 삭제되면 자식도 삭제 시켜준다.

즉, cascadetrue하면 post_tag row를 삭제 할 때
posttag엔티티 들도 삭제 될 수 있으니 false로 명시해야한다.

출처

쿼리빌더
remove, delete

마침

뭔가 간단해 보이는 기능인데,, 구현에 하루가 다 지나갔다..
TypeORM의 기능을 쓰는 것도 중요하지만
sql 쿼리를 먼저 이해하고 기능이 있으면 덧 붙여 쓰는게 우선인게 느껴졌다.

0개의 댓글