typeorm : subscriber (mysql 트리거와 비슷)

Gwonyeong·2023년 5월 15일
0

유키독

목록 보기
4/11

오늘은 nestjs로 백엔드 작업을 진행했다.

keyword 테이블

keywordUser테이블

나의 키워드를 저장하는 테이블은 위와 같다.
사용자가 keyword를 입력하면 keyword테이블에 데이터를 저장하고, keywordUser테이블에 유저의 아이디와 키워드의 아이디를 삽입해 user테이블과 연결시키는 구조이다.

나는 이전에 mysql trigger에 대해 얼핏 들은적이 있는데 테이블에 트리거를 걸어놓고
(트리거가 총의 방아쇠라는 뜻을 가지니까 특정 이벤트가 발생하면 테이블에 지정해놓은 이벤트를 실행한다.. 정도로 이해할 수 있었다.)

새로운 키워드를 입력한 유저가 생기면 keyword테이블의 count를 변화시키고 싶었다.
keywordUser테이블에서 해당 keywordId를 가진 row의 수를 세어 count에 넣어주면 될 일이다.

typeorm에서는 직접적으로 mysql의 trigger를 사용할 수는 없지만 subscriber라는 이름으로 비슷한 기능을 해낼 수 있다.

https://orkhan.gitbook.io/typeorm/docs/listeners-and-subscribers

공식문서에 사용하는 방법자체는 자세하게 나와있다.


내가 놓쳤던 부분은 typeorm의 forRoot 메소드를 이용할 때 설정에 subscribers라는 속성을 넣어줘야 한다는 점이다.

클래스는 잘 작성했고 AppModule의 providers에도 넣어줬는데 왜 안될까.. 한참 고민했다.

keywordUserSubscriber

import {
  EventSubscriber,
  EntitySubscriberInterface,
  InsertEvent,
  Repository,
} from 'typeorm';
import { Keyword, KeywordUser } from '../entities/keyword.entity';

@EventSubscriber()
export class KeywordUserSubscriber
  implements EntitySubscriberInterface<KeywordUser>
{
  constructor(private keyword: Repository<Keyword>) {}

  listenTo() {
    return KeywordUser;
  }

  beforeInsert(event: InsertEvent<KeywordUser>) {
    const keywordId = event.entity.keyword.id;
    

    // 새로운 User 엔티티가 추가되기 전에 실행됩니다.
  }
}

이와 같이 EntitySubscriberInterface를 implements 하여 구현할 수 있도록 상속을 받고, 이 클래스의 메소드를 활용하여 작성한다.

listenTo()로 특정 엔티티를 구독하고,
beforeInsert라는 이름 그대로 해당 데이터베이스에 데이터가 삽입되기 직전에 로직을 수행한다.

실제로 keywordId를 콘솔로 찍어보니 결과값이 잘 출력되었다.

메소드들의 이름이 직관적이여서 공식문서를 활용하면 여러 기능을 활용할 수 있을 것 같다.

profile
부동의 첫사랑

0개의 댓글

관련 채용 정보