nest를 활용한 쇼핑몰 프로젝트를 하는 도중 어떤 상품을 상세 조회 시, 해당하는 상품의 할인정보와 리뷰들 그 리뷰의 유저정보를 모두 가져오는 기능을 구현하면서
상품에 연결된 테이블을 4가지를 엮어서 가져오는 작업을 하게됐다.
user - review - Product - discount
erd는 위와 같이 그려져있고 실제 스키마도 그렇게 정의되어있다.
product에는 category테이블 도 연결되어있다.
createQueryBuilder는 typeORM에서 제공하는 로우쿼리를 비교적 쉽고 직관적으로 작성할 수 있는 친구인데,
직접 보면 더 쉽게 이해가 가능하다.
위에서 설명한 경우는 다음과 같이 작성한다.
async getById(id) {
const product = await this.createQueryBuilder('product')
.leftJoinAndSelect('product.category', 'category')
.leftJoinAndSelect('product.discount', 'discount')
.leftJoinAndSelect('product.review', 'review')
.leftJoinAndSelect('review.user', 'user')
.select([
'product.id',
'product.productName',
'category.name',
'discount.discountPrice',
'discount.discountRating',
'discount.startDate',
'discount.endDate',
'product.description',
'product.imgUrl',
'product.price',
'product.totalStock',
'review.id',
'review.content',
'review.userId',
'review.rating',
'user.email',
])
.where('product.id = :id', { id })
.getOne();
return product;
}
leftJoinAndSelect를 사용해서 해당 product나 다른 테이블에 연결된 테이블을 연결시킬 수 있고,
select안에 배열을 사용해서 필요한 내역들을 다음처럼 나열 후,
where로 식별하고 getOne()을 하면 된다.
그러면 다음처럼 나옴 ㅇㅇ
{
"id": 11,
"price": "40000",
"productName": "소주주주주주",
"totalStock": "300",
"description": "설명입니다.",
"imgUrl": "url",
"category": {
"name": "전통주"
},
"discount": {
"discountPrice": null,
"discountRating": 30,
"startDate": "2023.09.01",
"endDate": "2023.09.30"
},
"review": [
{
"id": 1,
"content": "aaaaaafffff",
"rating": 4,
"userId": 1,
"user": {
"email": "jjd0324@gmail.com"
}
}
]
}