Seize the day

[TypeORM] 테이블 relation 관계 없이 Join하기 (leftJoinMapOne, InnerJoinMapOne) 본문

개발/Node.js

[TypeORM] 테이블 relation 관계 없이 Join하기 (leftJoinMapOne, InnerJoinMapOne)

nofunfromdev 2024. 3. 26. 16:25

NestJS와 TypeORM을 사용하는 개발 과정에서, 서로 관계가 정의되지 않은 테이블 간에 조인이 필요한 상황이 발생했다. TypeORM은 주로 연관 관계를 통해 데이터를 처리하며, 필요한 경우 raw SQL 쿼리를 통해 직접 조회할 수도 있다. 그러나, QueryBuilder를 활용하면 더 유연하게 조인 작업을 수행할 수 있다.

TypeORM의 QueryBuilder를 사용하여 조인을 수행할 때 사용할 수 있는 메소드에는 innerJoin, innerJoinAndSelect, 그리고 innerJoinAndMapOne이 있다.

innerJoin

조인을 수행 하지만, 조인된 결과를 작동으로 매핑하지 않는다. 별도로 select 함수를 써줘야 한다.

innerJoinAndSelect

Join을 수행하고 Entity의 필트에 자동으로 매핑되어 쿼리 결과에 나온다.

관계가 있는 경우만 자동으로 매핑되어 나온다.

// innerJoinAndSelect 사용 시
const user = await userRepository
  .createQueryBuilder("user")
  .where("user.id = :userId", { userId: 1 })
  .innerJoinAndSelect("user.profile", "profile", "user.profileId = profile.id")
  .getOne();

관계가 없는 경우는 에러가 발생한다.
Relation with property path profile in entity was not found.

innerJoinAndMapOne

innerJoinAndMapOne 함수는 엔터티의 테이블과 내부 조인(inner join)을 수행하고, 조인으로 반환된 데이터를 엔터티의 어떤 속성에 매핑한다.
이 기능은 특정 데이터를 선택하고 그것을 가상의 속성에 매핑하고자 할 때 매우 유용하다.

즉, 데이터베이스 스키마에 relation을 설정하지 않고 데이터를 매핑할 때 사용 할 수있다.

// innerJoinAndMapOne 사용 시
const user = await userRepository
  .createQueryBuilder("user")
  .where("user.id = :userId", { userId: 1 })
  .innerJoinAndMapOne("user.profile", Profile, "profile", "user.profileId = profile.id")
  .getOne();

 

 

innerJoinAndMapOne("user.profile", Profile, "profile", "user.profileId = profile.id")

  1. mapToProperty: 매핑할 대상 엔터티의 경로, 이 경로는 조인된 데이터를 매핑할 엔터티 내의 속성을 나타냅니다. 예를 들어, "user.profile"는 User 엔터티의 profile 속성에 데이터를 매핑하겠다는 것을 의미한다.
  2. entity: 조인할 대상 엔터티
  3. alias: 조인할 대상 엔터티의 별칭
  4. condition (선택적): 조인을 수행할 조건으로, SQL의 ON 절에 해당하는 부분이다. 조인할 두 테이블 간의 관계를 정의한다.
  5. parameters (선택적): 조인 조건에 사용될 파라미터의 값을 포함하는 객체
{
  "id": 1,
  "name": "John Doe",
  "profileId": 2,
  "profile": {
    "id": 2,
    "bio": "Lorem ipsum",
    "userId": 1
  }
}

 

위와 같은 결과를 얻을 수 있다. 

반응형
Comments