joinAndMap의 유용성 {typeorm}
typeorm.io # Joining and mapping functionaility 를 참고할 것. 엔티티의 특정 필드에 조인 셀렉션을 명시적으로 매핑하고 싶은 경우에 이 메서드를 사용하면 된다.
Q. 그냥
joinAndSelect
하니까 걱정없이 매핑 되던데?
대부분의 경우에는 되겠지. 하지만 셀렉션 없이 매핑이 안되는 프로퍼티가 분명히 존재한단 사실을 알고 있어야 한다. 공식문서의 예시는 user.profilePhoto
를 예로 들고 있다. 이 프로퍼티는 아마 컬럼이 아니라 JS 런타임 내에서 쓰일 편의용 프로퍼티일 것이다.
export class User {
/// ...
profilePhoto: Photo
}
const user = await createQueryBuilder("user")
.leftJoinAndMapOne(
/*mapToProperty*/"user.profilePhoto",
/*property*/"user.photos",
/*alias*/"photo",
/*condition*/"photo.isForProfile = TRUE",
)
.where("user.name = :name", { name: "Timber" })
.getOne();
만약 위의 예시에서 leftJoinAndSelect
만을 사용했다면 user.photos
만 매핑이 자동으로 될 것이고, profilePhoto
는 addSelect('userProfilePhoto')
를 추가하여 수동으로 매핑하는 코드를 작성해야 했을 것이다:
const user = await createQueryBuilder("user")
.leftJoinAndSelect(
/*property*/"user.photos",
/*alias*/"photo",
)
.where("user.name = :name", { name: "Timber" })
.getOne();
if (user && user.photos) {
user.profilePhoto =
user.photos.find((photo) => photo.isForProfile === true));
}
내가 사용한 예시#
/**
* 연관 펀딩에 달린 모든 삭제되지 않은 댓글들을 반환한다.
* @param fundUuid
* @returns Comment[]
*/
async findMany(fundUuid: string): Promise<GetCommentDto[]> {
const fundingQb = this.fundingRepository
.createQueryBuilder('funding')
.leftJoinAndSelect(
'funding.comments',
'comment',
'comment.isDel = :isDel',
{ isDel: false },
)
.leftJoinAndSelect('comment.author', 'author')
.leftJoinAndMapOne(
'author.image', // map to property 'image' of 'author'
'image', // property name of 'author'
'authorImage', // alias of 'image' table
`
(author.defaultImgId IS NOT NULL AND authorImage.imgId = author.defaultImgId)
OR
(author.defaultImgId IS NULL AND authorImage.subId = author.userId AND authorImage.imgType = :imgType)
`,
{ imgType: ImageType.User },
)
.where('funding.fundUuid = :fundUuid', { fundUuid })
.orderBy('comment.regAt', 'DESC');
Logger.log(fundingQb.getSql());
const funding = await fundingQb.getOne();
if (!funding) {
throw this.g2gException.FundingNotExists;
}
return funding?.comments.map(convertToGetCommentDto) ?? [];
}