이번 로그에서는 TypeORM을 이용하여 Join하는 방법에 대해 기록하고자 한다.
TypeORM에서는 Query Builer라고 하는 쿼리 검색을 도와주는 강력한 헬퍼기능이 있다. 이 Query Builder를 이용하여 Left, Inner 조인이 가능하며 여러 Where절을 같이 사용하여 원하는 데이터를 만들 수 있다.
그럼 먼저 간단히 아래 소스코드를 보며 Join하는 방법에 대해 살펴보자.
const house = await getRepository(House)
.createQueryBuilder('house')
.leftJoinAndSelect('house.user', 'user')
.where('house.id = :id', { id: 1 })
.getOne();
이 소스코드는 House 모델에 1:N으로 관계되어져 있는 User id 1의 정보를 Left Join해서 데이터를 가져오는 코드이다.
위와 같이 간단히 원하는 모델의 프로퍼티에 조인하고자 하는 모델을 적어주는 것만으로 간단히 조인이 가능하다. !
여러 모델을 붙이는 것도 간단한데 아래 소스 코드를 보자.
const houses = await getRepository(House)
.createQueryBuilder('house')
.leftJoinAndSelect('house.amenity', 'amenity')
.leftJoinAndSelect('house.images', 'image')
.where('house.plan = :plan', { plan: plan })
.andWhere('house.type = :type', { type: type })
.andWhere('house.year = :year', { year: year })
.andWhere('house.access = :access', { access: access })
.andWhere('house.adminDistrict = :adminDistrict', {
adminDistrict: adminDistrict,
})
.getMany();
여러 개를 동시에 조인할 때에는 leftJoinAndSelect를 한번 더 작성하면 된다. 아주 간단하다.
추가적으로 where절로 조건을 주는 경우 위와 같이 andWhere을 하게되면 모든 조건이 맞는 데이터만 가져오게 되고 orWhere을 하게되면 어느 쪽이던 맞는 데이터를 가져오게 된다.
공식문서에 나와 있는 예제 코드를 보며 차이점을 확인해 보도록 하겠다.
먼저, leftJoinAndSelect의 예제코드이다. 아래 코드의 leftJoinAndSelect는 "Timber"라는 name을 갖는 유저를 로드하게 되며, 그 유저의 모든 사진들을 조인하여 같이 로드하게 된다.
const user = await createQueryBuilder("user")
.leftJoinAndSelect("user.photos", "photo")
.where("user.name = :name", { name: "Timber" })
.getOne();
다음, leftJoin을 하게 되면 selection 없이 데이터를 로드할 수 있다. 즉, "Timber"라는 name을 갖는 유저를 로드하지만 그 유저의 모든 사진을 같이 반환하지는 않는다.
const user = await createQueryBuilder("user")
.leftJoin("user.photos", "photo")
.where("user.name = :name", { name: "Timber" })
.getOne();