반응형
TypeORM에서 여러개의 테이블을 조인하는 방법
예시 코드는 nest.js에서 작성되었다.
Entity
...
@Entity()
export class Product {
@PrimaryGeneratedColumn()
product_no: number;
@Column({ type: 'varchar', length: 50 })
product_title: string;
@Column({ type: 'varchar', length: 200 })
product_content: string;
@Column({ type: 'varchar', length: 25 })
product_price: string;
@Column({ type: 'integer', default: 0 })
product_view: number;
@Column({ type: 'boolean', default: false })
product_state: boolean;
@CreateDateColumn()
createdAt: Date;
@Column({
type: 'varchar',
length: 15,
default: 'N',
})
deleted: string;
@OneToMany(() => Image, (image) => image.product)
images: Image[];
@OneToMany(
() => ProductCategory,
(productCategory) => productCategory.product,
)
productCategories: ProductCategory[];
@OneToMany(() => Wish, (wish) => wish.product)
wishes: Wish[];
@OneToMany(() => Comment, (comment) => comment.product)
comments: Comment[];
@ManyToOne(() => User, (user) => user.products)
@JoinColumn({ name: 'product_user_no' })
user: User;
}
Query
export class ProductService {
async findOne(product_no: number) {
const product = await getRepository(Product)
// 아래 p는 Product의 별칭
.createQueryBuilder('p')
.leftJoinAndSelect('p.images', 'image')
.leftJoinAndSelect('p.productCategories', 'productCategory')
.leftJoinAndSelect('productCategory.category', 'category')
.leftJoinAndSelect('p.user', 'seller')
.leftJoinAndSelect('p.comments', 'comment')
.leftJoinAndSelect('comment.user', 'commentWriter')
.leftJoinAndSelect('comment.recomments', 'recomment')
.leftJoinAndSelect('recomment.user', 'recommentWriter')
.leftJoinAndSelect('seller.deals', 'deal')
.leftJoinAndSelect('deal.addressArea', 'addressArea')
.leftJoinAndSelect('addressArea.addressCity', 'addressCity')
.leftJoinAndSelect('p.wishes', 'wish')
.select([
// 상품 기본정보
'p.product_no',
'p.product_title',
'p.product_content',
'p.product_price',
'p.product_view',
'p.product_state',
'p.createdAt',
'p.deleted',
// 상품 이미지
'image.image_order',
'image.image_src',
// 카테고리
'productCategory.product_category_no',
'category.category_name',
// 판매자
'seller.user_no',
'seller.user_tel',
'seller.user_profile_image',
'seller.user_nick',
// 거래 희망 지역
'deal.deal_no',
'addressArea.area_name',
'addressCity.city_name',
// 댓글
'comment.comment_no',
'comment.comment_content',
'commentWriter.user_no',
'commentWriter.user_profile_image',
'commentWriter.user_nick',
// 대댓글
'recomment.recomment_no',
'recomment.recomment_content',
'recommentWriter.user_no',
'recommentWriter.user_profile_image',
'recommentWriter.user_nick',
])
.loadRelationCountAndMap('p.wishCount', 'p.wishes', 'wishCount', (qb) =>
qb.where('wishCount.deleted = :value', { value: 'N' }),
)
.where('p.product_no = :product_no', { product_no })
.getMany();
return product;
}
설명
- leftJoinAndSelect로 조인하고 싶은 테이블들을 명시한다.
- .leftJoinAndSelect('p.조인된테이블명', '별칭')
- select문 안에 찾고싶은 컬럼들을 정의한다.
- loadRelationCountAndMap은 서브쿼리 개념으로 추가적으로 쿼리를 생성한다.
- 갯수를 새는 쿼리를 추가할때 사용하자
- 위 예시에서는 상품의 찜 갯수
- 실제로 실행시켜보면 쿼리를 2개 날린다.
- loadRelationCountAndMap을 준 이유는 따로 COUNT를 사용할 경우 사용된 모든 테이블의 아이디를 GROUPBY 해줘야 했기 때문이다.
반응형
'Programming > Nest.js' 카테고리의 다른 글
[Nest.js] Nest.js에서 node-cache사용하는 방법 (0) | 2022.05.28 |
---|---|
[Nest.js] OverView: 첫번째 단계 (0) | 2022.05.23 |
[Nest.js] Nest.js에서 소셜로그인을 구현하는 방법 (feat.Naver) (0) | 2022.05.23 |
[TypeORM] typeORM에서 평균(AVG) 구하기 (0) | 2022.05.23 |