공부한 내용
No Offset 오작동 문제 해결 : 로직 수정
1. 기존 방식에서 오작동이 있는 걸 확인하고 수정해줬다.
•
핵심은 return member.totalPoint.loe(lastPoint).and(member.id.gt(lastId)); 가 아래로 바꼈단 것이다.
return (member.totalPoint.lt(lastPoint))
.or(member.totalPoint.eq(lastPoint).and(member.id.gt(lastId)));
Java
복사
•
왜 이것이 문제였냐면,
◦
위 코드를 넣었던 의도는 현재 더보기 방식이 포인트가 작은 애들을 보여주는 방식인데, 포인트가 같은 애들을 안 보여줄 순 없으니 그 경우엔 아이디가 큰 애들을 보여주기 위함이었다.
◦
허나, 기존의 (member.totalPoint ≤ lastPoint) && (membe.id > lastId) 는 포인트가 작거나 같으면서, 아이디가 큰 애들을 보여주게 되어 포인트가 작은데 아이디가 작은 애들은 보여주지 못한다. 쉽게 말해, 의도한 대로 동작하지 않는다.
◦
따라서, 이를 (member.totalPoint < lastPoint) || { (member.totalPoint == lastPoint) && member.id > lastId) } 로 분류해줌으로써 의도한 대로 동작하게 수정해줬다.
◦
해당 코드는 더보기 방식에서 포인트가 큰 순서대로 보여주고, 아이디가 같은 경우엔 아이디를 작은 순서대로 보여준다.
•
전체 코드는 아래와 같다.
◦
기존 코드
@Override
public List<Member> findByTotalPointRanking(int pageSize, Long lastId, Integer lastPoint) {
return queryFactory
.select(member)
.from(member)
.where(whereClauseTotal(lastId, lastPoint))
.orderBy(member.totalPoint.desc(), member.id.asc())
.limit(pageSize)
.fetch();
}
private BooleanExpression whereClauseTotal(Long lastId, Integer lastPoint) {
if(lastId != null && lastPoint != null) {
return member.totalPoint.loe(lastPoint).and(member.id.gt(lastId));
}
return null;
}
Java
복사
◦
수정한 코드
private BooleanExpression whereClauseTotal(Long lastId, Integer lastPoint) {
if(lastId != null && lastPoint != null) {
return (member.totalPoint.lt(lastPoint))
.or(member.totalPoint.eq(lastPoint).and(member.id.gt(lastId)));
}
return null;
}
Java
복사
2. 더보기 마지막 페이지를 알려주기 위해, 다음 페이지 유무를 같이 보내주기로 했다.
•
이를 위해 pageSize보다 하나 크게 데이터를 가져오게 했다. 하나 더 가져온 데이터가 존재하면 다음 페이지가 있는 것이고, 존재하지 않는다면 다음 페이지가 없는 것이다.
if (range.equals("all")) {
memberList = memberRepository.findByTotalPointRanking(pageSize, lastId, lastPoint);
}
boolean nextPage = false;
if (memberList.size() == pageSize + 1) {
nextPage = true;
memberList.remove(pageSize + 0); // pageSize+1개만큼 가져옴. 마지막 원소 삭제 필요
}
Java
복사
@Override
public List<Member> findByTotalPointRanking(int pageSize, Long lastId, Integer lastPoint) {
return queryFactory
.select(member)
.from(member)
.where(whereClauseTotal(lastId, lastPoint))
.orderBy(member.totalPoint.desc(), member.id.asc())
.limit(pageSize + 1)
.fetch();
}
Java
복사
stream 쓰는 법 두 가지
return CustomizedArtWorkResponse.builder()
.nextPage(nextPage)
.artworks(artworks.stream()
.map(m -> CustomizedArtWorkResponse.ArtWorkDto.from(m, awsStorageUrl, memberPreferredArtWorkRepository.existsByMemberAndArtWork(member, m)))
.collect(Collectors.toList()))
.build();
Java
복사
return BiddingListResponse.builder()
.artWork(BiddingListResponse.ArtWorkDto.of(artWork, getTopPrice(artWork), fileManager.getFullPath(artWork.getMainImage())))
.auction(BiddingListResponse.AuctionDto.from(artWork.getAuction()))
.biddingList(biddingList.stream().map(BiddingListResponse.BiddingDto::from)
.collect(Collectors.toList()))
.totalBiddingCount(biddingList.size())
.build();
Java
복사
구글 프로필 이미지 저장 (특정 문자열 시작)
•
링크 그대로 받아와서 저장하는 거 까진 문제 없는데, 링크를 보내줄 때 aws s3에서 꺼내온 이미지 처리와 구분해줘야 했다
•
그 이유는, aws s3 버킷에 넣는 친구들은 db에 버킷이름만 저장해서이다.
•
aws s3 주소가 바뀔까봐 그렇게 했는데, 구글 프로필 이미지와 구분해줘야 하는 불편함이 있었다.
•
잘못 보내지는 예시
•
이를 해결하기 위해 https://lh3.googleusercontent.com 으로 시작하는 것들은 그대로 보내게 해줬고, 아닌 것들은 aws s3 주소를 붙여서 보내게 해줬다. 근데, 더 범용성 있게 그냥 https:// 로 시작하는 것들로 필터링했다.
하루 정리
TIL 작성하기
BeachCombine
랭킹 오작동 해결
랭킹 마지막페이지 구분 로직 추가
구글 프로필 이미지 저장 로직 추가