From e72b3d0660a808feb0dead479dae85e6fc19888c Mon Sep 17 00:00:00 2001 From: 70825 Date: Mon, 16 Oct 2023 12:12:52 +0900 Subject: [PATCH] =?UTF-8?q?refactor:=20=EC=A0=95=EB=A0=AC=EB=A7=8C=20?= =?UTF-8?q?=ED=95=98=EB=8A=94=20=EC=84=9C=EB=B9=84=EC=8A=A4=20=ED=81=B4?= =?UTF-8?q?=EB=9E=98=EC=8A=A4=20=EB=B6=84=EB=A6=AC,=20Tag=EA=B9=8C?= =?UTF-8?q?=EC=A7=80=20=EA=B0=80=EC=A0=B8=EC=98=AC=20=EC=88=98=20=EC=9E=88?= =?UTF-8?q?=EB=8F=84=EB=A1=9D=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../review/application/ReviewService.java | 52 ++++++-------- .../application/SortingReviewService.java | 67 +++++++++++++++++++ .../funeat/review/dto/SortingReviewDto.java | 57 +++++----------- ...o.java => SortingReviewDtoWithoutTag.java} | 29 ++++---- .../persistence/ReviewCustomRepository.java | 8 +-- .../persistence/ReviewRepositoryImpl.java | 22 +++--- 6 files changed, 131 insertions(+), 104 deletions(-) create mode 100644 backend/src/main/java/com/funeat/review/application/SortingReviewService.java rename backend/src/main/java/com/funeat/review/dto/{TestSortingReviewDto.java => SortingReviewDtoWithoutTag.java} (57%) diff --git a/backend/src/main/java/com/funeat/review/application/ReviewService.java b/backend/src/main/java/com/funeat/review/application/ReviewService.java index 5c3d34346..42c11eba7 100644 --- a/backend/src/main/java/com/funeat/review/application/ReviewService.java +++ b/backend/src/main/java/com/funeat/review/application/ReviewService.java @@ -28,11 +28,9 @@ import com.funeat.review.dto.SortingReviewDto; import com.funeat.review.dto.SortingReviewRequest; import com.funeat.review.dto.SortingReviewsResponse; -import com.funeat.review.dto.TestSortingReviewDto; import com.funeat.review.exception.ReviewException.ReviewNotFoundException; import com.funeat.review.persistence.ReviewRepository; import com.funeat.review.persistence.ReviewTagRepository; -import com.funeat.review.specification.SortingReviewSpecification; import com.funeat.tag.domain.Tag; import com.funeat.tag.persistence.TagRepository; import java.util.List; @@ -42,7 +40,6 @@ import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.domain.Specification; import org.springframework.stereotype.Service; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.multipart.MultipartFile; @@ -54,9 +51,7 @@ public class ReviewService { private static final int START = 0; private static final int ONE = 1; private static final String EMPTY_URL = ""; - private static final int PAGE_SIZE = 10; - private static final boolean EXIST_NEXT_DATA = true; - private static final boolean NOT_EXIST_NEXT_DATA = false; + private static final int REVIEW_PAGE_SIZE = 10; private final ReviewRepository reviewRepository; private final TagRepository tagRepository; @@ -65,12 +60,13 @@ public class ReviewService { private final ProductRepository productRepository; private final ReviewFavoriteRepository reviewFavoriteRepository; private final ImageUploader imageUploader; + private final SortingReviewService sortingReviewService; public ReviewService(final ReviewRepository reviewRepository, final TagRepository tagRepository, final ReviewTagRepository reviewTagRepository, final MemberRepository memberRepository, final ProductRepository productRepository, final ReviewFavoriteRepository reviewFavoriteRepository, - final ImageUploader imageUploader) { + final ImageUploader imageUploader, final SortingReviewService sortingReviewService) { this.reviewRepository = reviewRepository; this.tagRepository = tagRepository; this.reviewTagRepository = reviewTagRepository; @@ -78,6 +74,7 @@ public ReviewService(final ReviewRepository reviewRepository, final TagRepositor this.productRepository = productRepository; this.reviewFavoriteRepository = reviewFavoriteRepository; this.imageUploader = imageUploader; + this.sortingReviewService = sortingReviewService; } @Transactional @@ -148,40 +145,29 @@ public void updateProductImage(final Long reviewId) { public SortingReviewsResponse sortingReviews(final Long productId, final Long memberId, final SortingReviewRequest request) { - final Member member = memberRepository.findById(memberId) + final Member findMember = memberRepository.findById(memberId) .orElseThrow(() -> new MemberNotFoundException(MEMBER_NOT_FOUND, memberId)); - final Product product = productRepository.findById(productId) + final Product findProduct = productRepository.findById(productId) .orElseThrow(() -> new ProductNotFoundException(PRODUCT_NOT_FOUND, productId)); - final List sortingReviews = getSortingReviews(member, product, request); - if (sortingReviews.size() > PAGE_SIZE) { - final List resizeSortingReviews = sortingReviews.subList(START, PAGE_SIZE); - return SortingReviewsResponse.toResponse(resizeSortingReviews, EXIST_NEXT_DATA); - } - return SortingReviewsResponse.toResponse(sortingReviews, NOT_EXIST_NEXT_DATA); - } + final List sortingReviews = sortingReviewService.getSortingReviews(findMember, findProduct, request); + final int resultSize = getResultSize(sortingReviews); - private List getSortingReviews(final Member member, final Product product, - final SortingReviewRequest request) { - final Long lastReviewId = request.getLastReviewId(); - final String sortOption = request.getSort(); + final List resizeSortingReviews = sortingReviews.subList(START, resultSize); + final Boolean hasNext = hasNextPage(sortingReviews); - final Specification specification = getSortingSpecification(product, sortOption, lastReviewId); - final List sortingReviewsTest = reviewRepository.getSortingReview(member, specification, - sortOption); - return sortingReviewsTest.stream() - .map(SortingReviewDto::toDto) - .collect(Collectors.toList()); + return SortingReviewsResponse.toResponse(resizeSortingReviews, hasNext); } - private Specification getSortingSpecification(final Product product, final String sortOption, - final Long lastReviewId) { - if (lastReviewId == START) { - return SortingReviewSpecification.sortingFirstPageBy(product); + private int getResultSize(final List sortingReviews) { + if (sortingReviews.size() <= REVIEW_PAGE_SIZE) { + return sortingReviews.size(); } - final Review lastReview = reviewRepository.findById(lastReviewId) - .orElseThrow(() -> new ReviewNotFoundException(REVIEW_NOT_FOUND, lastReviewId)); - return SortingReviewSpecification.sortingBy(product, sortOption, lastReview); + return REVIEW_PAGE_SIZE; + } + + private Boolean hasNextPage(final List sortingReviews) { + return sortingReviews.size() > REVIEW_PAGE_SIZE; } public RankingReviewsResponse getTopReviews() { diff --git a/backend/src/main/java/com/funeat/review/application/SortingReviewService.java b/backend/src/main/java/com/funeat/review/application/SortingReviewService.java new file mode 100644 index 000000000..89c81856a --- /dev/null +++ b/backend/src/main/java/com/funeat/review/application/SortingReviewService.java @@ -0,0 +1,67 @@ +package com.funeat.review.application; + +import static com.funeat.review.exception.ReviewErrorCode.REVIEW_NOT_FOUND; + +import com.funeat.member.domain.Member; +import com.funeat.product.domain.Product; +import com.funeat.review.domain.Review; +import com.funeat.review.dto.SortingReviewDto; +import com.funeat.review.dto.SortingReviewDtoWithoutTag; +import com.funeat.review.dto.SortingReviewRequest; +import com.funeat.review.exception.ReviewException.ReviewNotFoundException; +import com.funeat.review.persistence.ReviewRepository; +import com.funeat.review.specification.SortingReviewSpecification; +import com.funeat.tag.persistence.TagRepository; +import java.util.List; +import java.util.stream.Collectors; +import org.springframework.data.jpa.domain.Specification; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +@Service +@Transactional(readOnly = true) +public class SortingReviewService { + + private static final int FIRST_PAGE = 0; + + private final ReviewRepository reviewRepository; + private final TagRepository tagRepository; + + public SortingReviewService(final ReviewRepository reviewRepository, final TagRepository tagRepository) { + this.reviewRepository = reviewRepository; + this.tagRepository = tagRepository; + } + + public List getSortingReviews(final Member member, final Product product, + final SortingReviewRequest request) { + final Long lastReviewId = request.getLastReviewId(); + final String sortOption = request.getSort(); + + final Specification specification = getSortingSpecification(product, sortOption, lastReviewId); + final List sortingReviewDtoWithoutTags = reviewRepository.getSortingReview(member, + specification, sortOption); + final List sortingReviewDtos = addTagsToSortingReviews(sortingReviewDtoWithoutTags); + + return sortingReviewDtos; + } + + private List addTagsToSortingReviews( + final List sortingReviewDtoWithoutTags) { + return sortingReviewDtoWithoutTags.stream() + .map(reviewDto -> SortingReviewDto.toDto(reviewDto, + tagRepository.findTagsByReviewId(reviewDto.getId()))) + .collect(Collectors.toList()); + } + + private Specification getSortingSpecification(final Product product, final String sortOption, + final Long lastReviewId) { + if (lastReviewId == FIRST_PAGE) { + return SortingReviewSpecification.sortingFirstPageBy(product); + } + + final Review lastReview = reviewRepository.findById(lastReviewId) + .orElseThrow(() -> new ReviewNotFoundException(REVIEW_NOT_FOUND, lastReviewId)); + + return SortingReviewSpecification.sortingBy(product, sortOption, lastReview); + } +} diff --git a/backend/src/main/java/com/funeat/review/dto/SortingReviewDto.java b/backend/src/main/java/com/funeat/review/dto/SortingReviewDto.java index 001cd8f2a..4a020166e 100644 --- a/backend/src/main/java/com/funeat/review/dto/SortingReviewDto.java +++ b/backend/src/main/java/com/funeat/review/dto/SortingReviewDto.java @@ -11,7 +11,6 @@ import java.util.Collections; import java.util.List; import java.util.Objects; -import java.util.Optional; import java.util.stream.Collectors; public class SortingReviewDto { @@ -46,22 +45,24 @@ public SortingReviewDto(final Long id, final String userName, final String profi this.createdAt = createdAt; } - public static SortingReviewDto toDto(final TestSortingReviewDto dto) { - final Boolean isFavorite = checkingFavorite(dto.getFavorite()); + public static SortingReviewDto toDto(final SortingReviewDtoWithoutTag sortingReviewDto, final List tags) { + final List tagDtos = tags.stream() + .map(TagDto::toDto) + .collect(Collectors.toList()); + final Boolean isFavorite = checkingFavorite(sortingReviewDto.getFavorite()); return new SortingReviewDto( - dto.getId(), - dto.getUserName(), - dto.getProfileImage(), - dto.getImage(), - dto.getRating(), - Collections.emptyList(), - dto.getContent(), - dto.getRebuy(), - dto.getFavoriteCount(), + sortingReviewDto.getId(), + sortingReviewDto.getUserName(), + sortingReviewDto.getProfileImage(), + sortingReviewDto.getImage(), + sortingReviewDto.getRating(), + tagDtos, + sortingReviewDto.getContent(), + sortingReviewDto.getRebuy(), + sortingReviewDto.getFavoriteCount(), isFavorite, - dto.getCreatedAt() - ); + sortingReviewDto.getCreatedAt()); } private static Boolean checkingFavorite(final Boolean favorite) { @@ -71,34 +72,6 @@ private static Boolean checkingFavorite(final Boolean favorite) { return Boolean.TRUE; } - public static SortingReviewDto toDto(final SortingReviewDto sortingReviewDto, final List tags) { - final List tagDtos = tags.stream() - .map(TagDto::toDto) - .collect(Collectors.toList()); - - return new SortingReviewDto(sortingReviewDto.getId(), sortingReviewDto.getUserName(), - sortingReviewDto.getProfileImage(), sortingReviewDto.getImage(), sortingReviewDto.getRating(), tagDtos, - sortingReviewDto.getContent(), sortingReviewDto.isRebuy(), sortingReviewDto.getFavoriteCount(), - sortingReviewDto.isFavorite(), sortingReviewDto.getCreatedAt()); - } - - private static List findTagDtos(final Review review) { - return review.getReviewTags().stream() - .map(ReviewTag::getTag) - .map(TagDto::toDto) - .collect(Collectors.toList()); - } - - private static boolean findReviewFavoriteChecked(final Review review, final Member member) { - return review.getReviewFavorites() - .stream() - .filter(reviewFavorite -> reviewFavorite.getReview().equals(review)) - .filter(reviewFavorite -> reviewFavorite.getMember().equals(member)) - .findFirst() - .map(ReviewFavorite::getFavorite) - .orElse(false); - } - public Long getId() { return id; } diff --git a/backend/src/main/java/com/funeat/review/dto/TestSortingReviewDto.java b/backend/src/main/java/com/funeat/review/dto/SortingReviewDtoWithoutTag.java similarity index 57% rename from backend/src/main/java/com/funeat/review/dto/TestSortingReviewDto.java rename to backend/src/main/java/com/funeat/review/dto/SortingReviewDtoWithoutTag.java index 5a0b1f998..a98fdb947 100644 --- a/backend/src/main/java/com/funeat/review/dto/TestSortingReviewDto.java +++ b/backend/src/main/java/com/funeat/review/dto/SortingReviewDtoWithoutTag.java @@ -2,23 +2,24 @@ import java.time.LocalDateTime; -public class TestSortingReviewDto { +public class SortingReviewDtoWithoutTag { private Long id; - private String userName; - private String profileImage; - private String image; - private Long rating; - private String content; - private Boolean rebuy; - private Long favoriteCount; - private Boolean favorite; - private LocalDateTime createdAt; + private final String userName; + private final String profileImage; + private final String image; + private final Long rating; + private final String content; + private final Boolean rebuy; + private final Long favoriteCount; + private final Boolean favorite; + private final LocalDateTime createdAt; - public TestSortingReviewDto(final Long id, final String userName, final String profileImage, final String image, - final Long rating, final String content, - final Boolean rebuy, final Long favoriteCount, final Boolean favorite, - final LocalDateTime createdAt) { + public SortingReviewDtoWithoutTag(final Long id, final String userName, final String profileImage, + final String image, final Long rating, + final String content, final Boolean rebuy, final Long favoriteCount, + final Boolean favorite, + final LocalDateTime createdAt) { this.id = id; this.userName = userName; this.profileImage = profileImage; diff --git a/backend/src/main/java/com/funeat/review/persistence/ReviewCustomRepository.java b/backend/src/main/java/com/funeat/review/persistence/ReviewCustomRepository.java index cd9d9a908..e2dd79992 100644 --- a/backend/src/main/java/com/funeat/review/persistence/ReviewCustomRepository.java +++ b/backend/src/main/java/com/funeat/review/persistence/ReviewCustomRepository.java @@ -2,13 +2,13 @@ import com.funeat.member.domain.Member; import com.funeat.review.domain.Review; -import com.funeat.review.dto.TestSortingReviewDto; +import com.funeat.review.dto.SortingReviewDtoWithoutTag; import java.util.List; import org.springframework.data.jpa.domain.Specification; public interface ReviewCustomRepository { - List getSortingReview(final Member loginMember, - final Specification specification, - final String sortField); + List getSortingReview(final Member loginMember, + final Specification specification, + final String sortField); } diff --git a/backend/src/main/java/com/funeat/review/persistence/ReviewRepositoryImpl.java b/backend/src/main/java/com/funeat/review/persistence/ReviewRepositoryImpl.java index ad408b0d0..ae47f7127 100644 --- a/backend/src/main/java/com/funeat/review/persistence/ReviewRepositoryImpl.java +++ b/backend/src/main/java/com/funeat/review/persistence/ReviewRepositoryImpl.java @@ -3,7 +3,7 @@ import com.funeat.member.domain.Member; import com.funeat.member.domain.favorite.ReviewFavorite; import com.funeat.review.domain.Review; -import com.funeat.review.dto.TestSortingReviewDto; +import com.funeat.review.dto.SortingReviewDtoWithoutTag; import java.util.List; import javax.persistence.EntityManager; import javax.persistence.PersistenceContext; @@ -26,11 +26,11 @@ public class ReviewRepositoryImpl implements ReviewCustomRepository { private EntityManager em; @Override - public List getSortingReview(final Member loginMember, - final Specification specification, - final String sortOption) { + public List getSortingReview(final Member loginMember, + final Specification specification, + final String sortOption) { final CriteriaBuilder cb = em.getCriteriaBuilder(); - final CriteriaQuery cq = cb.createQuery(TestSortingReviewDto.class); + final CriteriaQuery cq = cb.createQuery(SortingReviewDtoWithoutTag.class); final Root root = cq.from(Review.class); // sortField, sortOrder @@ -52,19 +52,19 @@ public List getSortingReview(final Member loginMember, .orderBy(getOrderBy(root, cb, sortField, sortOrder)); // limit - final TypedQuery query = em.createQuery(cq); + final TypedQuery query = em.createQuery(cq); query.setMaxResults(11); // result return query.getResultList(); } - private CompoundSelection getConstruct(final Root root, - final CriteriaBuilder cb, - final Join joinMember, - final Join leftJoinReviewFavorite) { + private CompoundSelection getConstruct(final Root root, + final CriteriaBuilder cb, + final Join joinMember, + final Join leftJoinReviewFavorite) { - return cb.construct(TestSortingReviewDto.class, + return cb.construct(SortingReviewDtoWithoutTag.class, root.get("id"), joinMember.get("nickname"), joinMember.get("profileImage"),