diff --git a/src/main/java/com/example/UMC/domain/review/config/QuerydslConfig.java b/src/main/java/com/example/UMC/domain/review/config/QuerydslConfig.java new file mode 100644 index 0000000..b7e8c19 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/review/config/QuerydslConfig.java @@ -0,0 +1,19 @@ +package com.example.UMC.domain.review.config; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import jakarta.persistence.EntityManager; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +@RequiredArgsConstructor +public class QuerydslConfig { + + private final EntityManager em; + + @Bean + public JPAQueryFactory jpaQueryFactory() { + return new JPAQueryFactory(em); + } +} diff --git a/src/main/java/com/example/UMC/domain/review/controller/ReviewController.java b/src/main/java/com/example/UMC/domain/review/controller/ReviewController.java new file mode 100644 index 0000000..47d2daa --- /dev/null +++ b/src/main/java/com/example/UMC/domain/review/controller/ReviewController.java @@ -0,0 +1,37 @@ +package com.example.UMC.domain.review.controller; + +import com.example.UMC.domain.review.entity.Review; +import com.example.UMC.domain.review.repository.ReviewQueryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +@RequestMapping("/reviews") +public class ReviewController { + + private final ReviewQueryRepository reviewQueryRepository; + + // 태스트 컨틀로러 + + /** + * 현재 이코드는 무한순회가 도는중 유저 - 리뷰 가 양방향 매핑이라 그래서 entity구조 그대로 하고 무한순회 안돌게 + * DTO사용이 필요해 보임. + */ + @GetMapping + public Page getReviews( + @RequestParam(required = false) Long storeId, + @RequestParam(required = false) String storeName, + @RequestParam(required = false) Long regionId, + @RequestParam(required = false) Integer star, + @RequestParam(defaultValue = "0") int page, + @RequestParam(defaultValue = "10") int size + ) { + Pageable pageable = PageRequest.of(page, size); + return reviewQueryRepository.findReviews(storeId, storeName, regionId, star, pageable); + } +} + diff --git a/src/main/java/com/example/UMC/domain/review/entity/Review.java b/src/main/java/com/example/UMC/domain/review/entity/Review.java index fa02b38..b726f62 100644 --- a/src/main/java/com/example/UMC/domain/review/entity/Review.java +++ b/src/main/java/com/example/UMC/domain/review/entity/Review.java @@ -26,6 +26,9 @@ public class Review extends BaseEntity { @Column(name = "content", columnDefinition = "TEXT") private String content; + @Column(name = "reply", length = 255) + private String reply; + @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "user_id", nullable = false) private User user; diff --git a/src/main/java/com/example/UMC/domain/review/repository/ReviewQueryRepository.java b/src/main/java/com/example/UMC/domain/review/repository/ReviewQueryRepository.java new file mode 100644 index 0000000..900a0d9 --- /dev/null +++ b/src/main/java/com/example/UMC/domain/review/repository/ReviewQueryRepository.java @@ -0,0 +1,16 @@ +package com.example.UMC.domain.review.repository; + +import com.example.UMC.domain.review.entity.Review; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public interface ReviewQueryRepository { + + Page findReviews( + Long storeId, // 가게ID 필터 + String storeName, // 가게명 필터 + Long regionId, // 지역ID 필터 + Integer star, // 별점 필터 + Pageable pageable // 페이징 + ); +} diff --git a/src/main/java/com/example/UMC/domain/review/repository/ReviewQueryRepositoryImpl.java b/src/main/java/com/example/UMC/domain/review/repository/ReviewQueryRepositoryImpl.java new file mode 100644 index 0000000..59894ce --- /dev/null +++ b/src/main/java/com/example/UMC/domain/review/repository/ReviewQueryRepositoryImpl.java @@ -0,0 +1,73 @@ +package com.example.UMC.domain.review.repository; + +import com.example.UMC.domain.review.entity.QReview; +import com.example.UMC.domain.review.entity.Review; +import com.example.UMC.domain.store.entity.QRegion; +import com.example.UMC.domain.store.entity.QStore; +import com.example.UMC.domain.user.entity.QUser; +import com.querydsl.core.BooleanBuilder; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Primary; +import org.springframework.data.domain.PageImpl; +import org.springframework.stereotype.Repository; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +import java.util.List; + +@Repository +@Primary //컨트롤러 테스트 용도로 잠시 붙힘 +@RequiredArgsConstructor +public class ReviewQueryRepositoryImpl implements ReviewQueryRepository { + + private final JPAQueryFactory queryFactory; + + @Override + public Page findReviews(Long storeId, String storeName, Long regionId, Integer star, Pageable pageable) { + // Q클래스들 import + QReview review = QReview.review; + QStore store = QStore.store; + QUser user = QUser.user; + QRegion region = QRegion.region; + + BooleanBuilder where = new BooleanBuilder(); + + if (storeId != null) { + where.and(store.id.eq(storeId)); + } else if (storeName != null && !storeName.isBlank()) { + where.and(store.name.containsIgnoreCase(storeName)); + } + + if (regionId != null) { + where.and(region.id.eq(regionId)); + } + + if (star != null) { + where.and(review.rating.eq(star)); + } + + List content = queryFactory + .selectFrom(review) + .join(review.user, user).fetchJoin() + .join(review.store, store).fetchJoin() + .join(review.region, region).fetchJoin() + .where(where) + .orderBy(review.createdAt.desc()) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + + Long total = queryFactory + .select(review.count()) + .from(review) + .join(review.user, user) + .join(review.store, store) + .join(review.region, region) + .where(where) + .fetchOne(); + + return new PageImpl<>(content, pageable, total == null ? 0 : total); + } +} + diff --git a/src/main/java/com/example/UMC/domain/review/repository/ReviewRepository.java b/src/main/java/com/example/UMC/domain/review/repository/ReviewRepository.java index ca5cc5c..6e3a507 100644 --- a/src/main/java/com/example/UMC/domain/review/repository/ReviewRepository.java +++ b/src/main/java/com/example/UMC/domain/review/repository/ReviewRepository.java @@ -7,7 +7,7 @@ import java.util.List; -public interface ReviewRepository extends JpaRepository { +public interface ReviewRepository extends JpaRepository, ReviewQueryRepository {