querydsl transform 사용
public List<MemberInfo> getMembersInfo() {
Map<Long, MemberInfo> resultMap = query
.from(member)
.join(address).on(address.member.id.eq(member.id))
.join(article).on(article.member.id.eq(member.id))
.transform(groupBy(member.id).as(new QMemberInfo(
member.username,
list(new QMemberInfo_AddressInfo(address.fullAddress)),
list(new QMemberInfo_ArticleInfo(article.title))
)));
return resultMap.keySet().stream()
.map(resultMap::get)
.collect(toList());
}
member ID를 key로 삼고 조회할 value들을→as(..) 담아 Map에 넣다
→ 이렇게하면 카다시안 곱이 발생, 중복 데이터제거하기위 해 set 사용. AddressInfo와 ArticleInfo가 중복되었음을 판별하기 위해 @EqualAndHashCode를 사용해야한다.
public List<MemberInfo> getMembersInfo() {
Map<Long, MemberInfo> resultMap = query
.from(member)
.join(address).on(address.member.id.eq(member.id))
.join(article).on(article.member.id.eq(member.id))
.transform(groupBy(member.id).as(new QMemberInfo(
member.username,
set(new QMemberInfo_AddressInfo(address.fullAddress)),
set(new QMemberInfo_ArticleInfo(article.title))
)));
return resultMap.keySet().stream()
.map(resultMap::get)
.collect(toList());
}
(@EqualAndHashCode? → equal 메서드: 같은내용인지, HashCode 메서드 : 같은 객체인지 판별할 수 있는 메서드를 자동으로 생성하는 어노테이션)
public NanaResponse.NanaDetailDto getNanaDetail(MemberInfoDto memberInfoDto, Long nanaId,
boolean isSearch) {
Language language = memberInfoDto.getLanguage();
// nana 찾아서
Nana nana = nanaRepository.findNanaById(nanaId)
.orElseThrow(() -> new NotFoundException(ErrorCode.NANA_NOT_FOUND.getMessage()));
// nanaTitle 찾아서
NanaTitle nanaTitle = nanaTitleRepository.findNanaTitleByNanaAndLanguage(nana,
language)
.orElseThrow(() -> new NotFoundException(ErrorCode.NANA_TITLE_NOT_FOUND.getMessage()));
if (isSearch) {
searchService.updateSearchVolumeV1(NANA, nana.getId());
}
// nanaTitle에 맞는 게시물 조회
List<NanaContent> nanaContentList = nanaContentRepository.findAllByNanaTitleOrderByNumber(
nanaTitle);
List<NanaResponse.NanaDetail> nanaDetails = new ArrayList<>();
boolean isPostInFavorite = favoriteService.isPostInFavorite(memberInfoDto.getMember(), NANA,
nanaTitle.getNana().getId());
Category category = categoryRepository.findByContent(NANA_CONTENT)
.orElseThrow(() -> new ServerErrorException("NANA_CONTENT에 해당하는 카테고리가 없습니다."));
for (NanaContent nanaContent : nanaContentList) {
List<Hashtag> hashtagList = hashtagRepository.findAllByLanguageAndCategoryAndPostId(
language, category, nanaContent.getId());
// 해시태그 정보 keyword 가져와서 list 형태로 바꾸기
List<String> stringKeywordList = getStringKeywordListFromHashtagList(hashtagList);
nanaDetails.add(
NanaResponse.NanaDetail.builder()
.number(nanaContent.getNumber())
.subTitle(nanaContent.getSubTitle())
.title(nanaContent.getTitle())
.imageUrl(nanaContent.getImageFile().getOriginUrl())
.content(nanaContent.getContent())
.additionalInfoList(getAdditionalInfoFromNanaContentEntity(nanaContent))
.hashtags(stringKeywordList)
.build());
}
return NanaResponse.NanaDetailDto.builder()
.originUrl(nanaTitle.getImageFile().getOriginUrl())
.subHeading(nanaTitle.getSubHeading())
.heading(nanaTitle.getHeading())
.version(nana.getVersion())
.notice(nanaTitle.getNotice())
.nanaDetails(nanaDetails)
.isFavorite(isPostInFavorite)
.build();
}
// nanaContent의 AdditionalInfo dto로 바꾸기
public List<NanaResponse.NanaAdditionalInfoDto> getAdditionalInfoFromNanaContentEntity(
NanaContent nanaContent) {
Set<NanaAdditionalInfo> eachInfoList = nanaContent.getInfoList();
// 순서 보장 위해 List 형으로 바꾸고
List<NanaAdditionalInfo> nanaAdditionalInfos = new ArrayList<>(eachInfoList);
//DTO 형태로 변환
List<NanaResponse.NanaAdditionalInfoDto> result = new ArrayList<>();
for (NanaAdditionalInfo info : nanaAdditionalInfos) {
result.add(NanaResponse.NanaAdditionalInfoDto.builder()
.infoEmoji(info.getInfoType().toString())
.infoKey(info.getInfoType().getDescription())
.infoValue(info.getDescription())
.build());
}
return result;
}
테스트 시간 → 859ms