Skip to content

Commit

Permalink
refactor: 리뷰 좋아요 조회 쿼리 분리 (#62)
Browse files Browse the repository at this point in the history
  • Loading branch information
pdohyung committed Apr 7, 2024
1 parent da7695e commit 48103e6
Show file tree
Hide file tree
Showing 9 changed files with 200 additions and 62 deletions.
6 changes: 3 additions & 3 deletions src/main/java/com/jisungin/api/user/UserController.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import com.jisungin.api.user.request.UserRatingGetAllRequest;
import com.jisungin.application.PageResponse;
import com.jisungin.application.review.response.RatingFindAllResponse;
import com.jisungin.application.review.response.ReviewContentResponse;
import com.jisungin.application.review.response.ReviewContentGetAllResponse;
import com.jisungin.application.user.UserService;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.GetMapping;
Expand All @@ -33,11 +33,11 @@ public ApiResponse<PageResponse<RatingFindAllResponse>> getUserRatings(
}

@GetMapping("/reviews")
public ApiResponse<PageResponse<ReviewContentResponse>> getReviewContents(
public ApiResponse<ReviewContentGetAllResponse> getReviewContents(
@ModelAttribute ReviewContentGetAllRequest request,
@Auth AuthContext authContext
) {
PageResponse<ReviewContentResponse> response = userService.getReviewContents(
ReviewContentGetAllResponse response = userService.getReviewContents(
authContext.getUserId(), request.toService());
return ApiResponse.ok(response);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
package com.jisungin.application.review.response;

import com.jisungin.application.PageResponse;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@Getter
@NoArgsConstructor
public class ReviewContentGetAllResponse {

private PageResponse<ReviewContentResponse> reviewContents;

private List<Long> userLikes;

@Builder
private ReviewContentGetAllResponse(PageResponse<ReviewContentResponse> reviewContents, List<Long> userLikes) {
this.reviewContents = reviewContents;
this.userLikes = userLikes;
}

public static ReviewContentGetAllResponse of(
PageResponse<ReviewContentResponse> reviewContents, List<Long> userLikes) {
return ReviewContentGetAllResponse.builder()
.reviewContents(reviewContents)
.userLikes(userLikes)
.build();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import lombok.Getter;
import lombok.NoArgsConstructor;

import java.util.List;

@Getter
@NoArgsConstructor
public class ReviewContentResponse {
Expand All @@ -27,8 +25,6 @@ public class ReviewContentResponse {

private String bookImage;

private List<Long> users;

@Builder
@QueryProjection
public ReviewContentResponse(
Expand All @@ -44,8 +40,4 @@ public ReviewContentResponse(
this.bookImage = bookImage;
}

public void addUsers(List<Long> users) {
this.users = users;
}

}
19 changes: 16 additions & 3 deletions src/main/java/com/jisungin/application/user/UserService.java
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@

import com.jisungin.application.PageResponse;
import com.jisungin.application.review.response.RatingFindAllResponse;
import com.jisungin.application.review.response.ReviewContentGetAllResponse;
import com.jisungin.application.review.response.ReviewContentResponse;
import com.jisungin.application.user.request.ReviewContentGetAllServiceRequest;
import com.jisungin.application.user.request.UserRatingGetAllServiceRequest;
import com.jisungin.domain.review.Review;
import com.jisungin.domain.review.repository.ReviewRepository;
import com.jisungin.domain.reviewlike.repository.ReviewLikeRepository;
import com.jisungin.domain.user.User;
import com.jisungin.domain.user.repository.UserRepository;
import com.jisungin.exception.BusinessException;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

import static com.jisungin.exception.ErrorCode.*;

@RequiredArgsConstructor
Expand All @@ -25,6 +28,8 @@ public class UserService {

private final ReviewRepository reviewRepository;

private final ReviewLikeRepository reviewLikeRepository;

public PageResponse<RatingFindAllResponse> getUserRatings(Long userId, UserRatingGetAllServiceRequest request) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new BusinessException(USER_NOT_FOUND));
Expand All @@ -33,12 +38,20 @@ public PageResponse<RatingFindAllResponse> getUserRatings(Long userId, UserRatin
user.getId(), request.getOrderType(), request.getRating(), request.getSize(), request.getOffset());
}

public PageResponse<ReviewContentResponse> getReviewContents(Long userId, ReviewContentGetAllServiceRequest request) {
public ReviewContentGetAllResponse getReviewContents(Long userId, ReviewContentGetAllServiceRequest request) {
User user = userRepository.findById(userId)
.orElseThrow(() -> new BusinessException(USER_NOT_FOUND));

return reviewRepository.findAllReviewContentOrderBy(
PageResponse<ReviewContentResponse> reviewContents = reviewRepository.findAllReviewContentOrderBy(
user.getId(), request.getOrderType(), request.getSize(), request.getOffset());

List<Long> reviewIds = reviewContents.getQueryResponse().stream()
.map(ReviewContentResponse::getReviewId)
.toList();

List<Long> likeReviewIds = reviewLikeRepository.findLikeReviewByReviewId(userId, reviewIds);

return ReviewContentGetAllResponse.of(reviewContents, likeReviewIds);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,10 @@
import lombok.extern.slf4j.Slf4j;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;

import static com.jisungin.domain.book.QBook.book;
import static com.jisungin.domain.review.QReview.review;
import static com.jisungin.domain.review.RatingOrderType.*;
import static com.jisungin.domain.reviewlike.QReviewLike.reviewLike;
import static com.jisungin.domain.user.QUser.user;

@Slf4j
Expand Down Expand Up @@ -49,16 +45,6 @@ public PageResponse<ReviewContentResponse> findAllReviewContentOrderBy(
log.info("--------------start--------------");
// 리뷰 내용을 가져온다. 쿼리 1회
List<ReviewContentResponse> reviewContents = getReviewContents(userId, orderType, size, offset);
// review_id를 Key로 해당 리뷰를 좋아요한 users를 가져온다. 쿼리 1회
Map<Long, List<Long>> reviewLikeUsers = getReviewLikeUsers();

reviewLikeUsers.forEach((reviewId, users) -> {
Optional<ReviewContentResponse> optionalReviewContents = reviewContents.stream()
.filter(content -> content.getReviewId().equals(reviewId))
.findFirst();

optionalReviewContents.ifPresent(reviewContent -> reviewContent.addUsers(users));
});

return PageResponse.<ReviewContentResponse>builder()
.queryResponse(reviewContents)
Expand All @@ -67,18 +53,6 @@ public PageResponse<ReviewContentResponse> findAllReviewContentOrderBy(
.build();
}

private Map<Long, List<Long>> getReviewLikeUsers() {
return queryFactory
.select(reviewLike.review.id, reviewLike.user.id)
.from(reviewLike)
.fetch()
.stream()
.collect(Collectors.groupingBy(
tuple -> tuple.get(0, Long.class), // reviewId
Collectors.mapping(tuple -> tuple.get(1, Long.class), Collectors.toList()) // List<Long> 유저 ID 리스트
));
}

private List<ReviewContentResponse> getReviewContents(
Long userId, RatingOrderType orderType, int size, int offset) {
return queryFactory
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,18 @@
import com.jisungin.domain.reviewlike.ReviewLike;
import com.jisungin.domain.user.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface ReviewLikeRepository extends JpaRepository<ReviewLike, Long> {

Optional<ReviewLike> findByUserAndReview(User user, Review review);

@Query("select rl.review.id from ReviewLike rl where rl.review.id in :reviewIds and rl.user.id = :userId")
List<Long> findLikeReviewByReviewId(Long userId, List<Long> reviewIds);

}
23 changes: 10 additions & 13 deletions src/test/java/com/jisungin/application/user/UserServiceTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
import com.jisungin.ServiceTestSupport;
import com.jisungin.application.PageResponse;
import com.jisungin.application.review.response.RatingFindAllResponse;
import com.jisungin.application.review.response.ReviewContentResponse;
import com.jisungin.application.review.response.ReviewContentGetAllResponse;
import com.jisungin.application.user.request.ReviewContentGetAllServiceRequest;
import com.jisungin.application.user.request.UserRatingGetAllServiceRequest;
import com.jisungin.domain.book.Book;
Expand Down Expand Up @@ -104,23 +104,20 @@ void getReviewContents() {
.build();

//when
PageResponse<ReviewContentResponse> result = userService.getReviewContents(user1.getId(), request);
ReviewContentGetAllResponse result = userService.getReviewContents(user1.getId(), request);

//then
assertThat(result.getTotalCount()).isEqualTo(20);
assertThat(result.getQueryResponse()).hasSize(4)
assertThat(result.getReviewContents().getTotalCount()).isEqualTo(20);
assertThat(result.getReviewContents().getQueryResponse()).hasSize(4)
.extracting(
"userImage", "userName", "rating", "content", "isbn", "title", "bookImage", "users")
"userImage", "userName", "rating", "content", "isbn", "title", "bookImage")
.containsExactly(
tuple("userImage", "김도형", 1.0, "리뷰 내용1", "1", "제목1", "bookImage",
List.of(user1.getId(), user2.getId())),
tuple("userImage", "김도형", 1.0, "리뷰 내용6", "6", "제목6", "bookImage",
List.of(user1.getId(), user2.getId())),
tuple("userImage", "김도형", 1.0, "리뷰 내용11", "11", "제목11", "bookImage",
List.of(user1.getId(), user2.getId())),
tuple("userImage", "김도형", 1.0, "리뷰 내용16", "16", "제목16", "bookImage",
List.of(user1.getId(), user2.getId()))
tuple("userImage", "김도형", 1.0, "리뷰 내용1", "1", "제목1", "bookImage"),
tuple("userImage", "김도형", 1.0, "리뷰 내용6", "6", "제목6", "bookImage"),
tuple("userImage", "김도형", 1.0, "리뷰 내용11", "11", "제목11", "bookImage"),
tuple("userImage", "김도형", 1.0, "리뷰 내용16", "16", "제목16", "bookImage")
);
assertThat(result.getUserLikes()).hasSize(4);
}

private static List<Book> createBooks() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,16 +220,12 @@ void getReviewContentOrderByRatingAsc() {
assertThat(result.getTotalCount()).isEqualTo(20);
assertThat(result.getQueryResponse()).hasSize(4)
.extracting(
"userImage", "userName", "rating", "content", "isbn", "title", "bookImage", "users")
"userImage", "userName", "rating", "content", "isbn", "title", "bookImage")
.containsExactly(
tuple("userImage", "김도형", 1.0, "리뷰 내용1", "1", "제목1", "bookImage",
List.of(user1.getId(), user2.getId())),
tuple("userImage", "김도형", 1.0, "리뷰 내용6", "6", "제목6", "bookImage",
List.of(user1.getId(), user2.getId())),
tuple("userImage", "김도형", 1.0, "리뷰 내용11", "11", "제목11", "bookImage",
List.of(user1.getId(), user2.getId())),
tuple("userImage", "김도형", 1.0, "리뷰 내용16", "16", "제목16", "bookImage",
List.of(user1.getId(), user2.getId()))
tuple("userImage", "김도형", 1.0, "리뷰 내용1", "1", "제목1", "bookImage"),
tuple("userImage", "김도형", 1.0, "리뷰 내용6", "6", "제목6", "bookImage"),
tuple("userImage", "김도형", 1.0, "리뷰 내용11", "11", "제목11", "bookImage"),
tuple("userImage", "김도형", 1.0, "리뷰 내용16", "16", "제목16", "bookImage")
);
}

Expand Down
Loading

0 comments on commit 48103e6

Please sign in to comment.