diff --git a/src/main/java/com/example/myongsick/domain/scrap/dto/ScrapCountResponse.java b/src/main/java/com/example/myongsick/domain/scrap/dto/ScrapCountResponse.java index e20380e..2250d81 100644 --- a/src/main/java/com/example/myongsick/domain/scrap/dto/ScrapCountResponse.java +++ b/src/main/java/com/example/myongsick/domain/scrap/dto/ScrapCountResponse.java @@ -1,17 +1,14 @@ package com.example.myongsick.domain.scrap.dto; +import com.querydsl.core.annotations.QueryProjection; import io.swagger.annotations.ApiModel; -import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; -import lombok.Setter; @Getter -@Setter @Builder @NoArgsConstructor -@AllArgsConstructor @ApiModel(description = "찜꽁 리스트 응답 객체 ( + 찜꽁수 포함 )") public class ScrapCountResponse { @@ -20,12 +17,28 @@ public class ScrapCountResponse { private String name; private String category; private String address; + private String contact; private String urlAddress; private String distance; - private String contact; private String latitude; private String longitude; private int scrapCount; + @QueryProjection + public ScrapCountResponse(Long storeId, String code, String name, String category, String address, + String contact, String urlAddress, String distance, String latitude, String longitude, + int scrapCount) { + this.storeId = storeId; + this.code = code; + this.name = name; + this.category = category; + this.address = address; + this.contact = contact; + this.urlAddress = urlAddress; + this.distance = distance; + this.latitude = latitude; + this.longitude = longitude; + this.scrapCount = scrapCount; + } public static ScrapCountResponse toDto(CountResponse countResponse) { return ScrapCountResponse.builder() diff --git a/src/main/java/com/example/myongsick/domain/scrap/repository/ScrapRepositoryCustom.java b/src/main/java/com/example/myongsick/domain/scrap/repository/ScrapRepositoryCustom.java new file mode 100644 index 0000000..3eb4b9e --- /dev/null +++ b/src/main/java/com/example/myongsick/domain/scrap/repository/ScrapRepositoryCustom.java @@ -0,0 +1,13 @@ +package com.example.myongsick.domain.scrap.repository; + +import com.example.myongsick.domain.scrap.dto.ScrapCountResponse; +import java.util.Optional; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.repository.query.Param; + +public interface ScrapRepositoryCustom { + Page findAllByCampusWithPaging(@Param("campus") String campus, Pageable pageable); + + Optional findByIdCustom(Long storeId); +} diff --git a/src/main/java/com/example/myongsick/domain/scrap/repository/ScrapRepositoryImpl.java b/src/main/java/com/example/myongsick/domain/scrap/repository/ScrapRepositoryImpl.java new file mode 100644 index 0000000..a1379f0 --- /dev/null +++ b/src/main/java/com/example/myongsick/domain/scrap/repository/ScrapRepositoryImpl.java @@ -0,0 +1,73 @@ +package com.example.myongsick.domain.scrap.repository; + +import static com.example.myongsick.domain.scrap.entity.QScrap.scrap; +import static com.example.myongsick.domain.scrap.entity.QStore.store; + +import com.example.myongsick.domain.scrap.dto.QScrapCountResponse; +import com.example.myongsick.domain.scrap.dto.ScrapCountResponse; +import com.example.myongsick.domain.scrap.entity.CampusType; +import com.example.myongsick.domain.scrap.entity.Store; +import com.querydsl.core.types.Order; +import com.querydsl.core.types.OrderSpecifier; +import com.querydsl.core.types.dsl.PathBuilder; +import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageImpl; +import org.springframework.data.domain.Pageable; +import org.springframework.data.domain.Sort; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class ScrapRepositoryImpl implements ScrapRepositoryCustom{ + private final JPAQueryFactory jpaQueryFactory; + + @Override + public Page findAllByCampusWithPaging(String campus, Pageable pageable) { + List result = jpaQueryFactory.select(new QScrapCountResponse(store.id.as("storeId"), store.code, store.name, store.category, store.address, store.contact, store.urlAddress, store.distance, store.latitude, store.longitude, store.scrapList.size().as("scrapCount"))) + .from(store) + .where(store.campus.eq(CampusType.valueOf(campus))) + .groupBy(store.code) + .orderBy(getOrderSpecifier(pageable.getSort()).stream().toArray(OrderSpecifier[]::new)) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + + Long count = jpaQueryFactory + .select(scrap.count()) + .from(scrap) + .fetchOne(); + + return new PageImpl<>(result, pageable, count); + } + + @Override + public Optional findByIdCustom(Long storeId) { + return Optional.ofNullable(jpaQueryFactory.select(new QScrapCountResponse(store.id.as("storeId"), store.code, store.name, store.category, store.address, store.contact, store.urlAddress, store.distance, store.latitude, store.longitude, store.scrapList.size().as("scrapCount"))) + .from(store) + .where(store.id.eq(storeId)) + .fetchOne()); + } + + private List getOrderSpecifier(Sort sort) { + List orderSpecifiers = new ArrayList<>(); + sort.stream() + .forEach(order -> { + Order direction = order.isAscending() ? Order.ASC : Order.DESC; + String property = order.getProperty(); + if(property.equals("scrapCount")) { + orderSpecifiers.add(new OrderSpecifier(direction, store.scrapList.size())); + } else if(property.equals("distance")) { + orderSpecifiers.add(new OrderSpecifier(direction, store.distance.castToNum(Long.class))); + } else { + PathBuilder orderByExpression = new PathBuilder(Store.class, "store"); + orderSpecifiers.add(new OrderSpecifier(direction, orderByExpression.get(property))); + } + }); + return orderSpecifiers; + } +} diff --git a/src/main/java/com/example/myongsick/domain/scrap/service/ScrapService.java b/src/main/java/com/example/myongsick/domain/scrap/service/ScrapService.java index fc58fbd..a2f3598 100644 --- a/src/main/java/com/example/myongsick/domain/scrap/service/ScrapService.java +++ b/src/main/java/com/example/myongsick/domain/scrap/service/ScrapService.java @@ -3,7 +3,6 @@ import com.example.myongsick.domain.scrap.dto.ScrapCountResponse; import com.example.myongsick.domain.scrap.dto.ScrapRequest; import com.example.myongsick.domain.scrap.dto.ScrapResponse; -import java.util.Optional; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; diff --git a/src/main/java/com/example/myongsick/domain/scrap/service/ScrapServiceImpl.java b/src/main/java/com/example/myongsick/domain/scrap/service/ScrapServiceImpl.java index ecbd245..08f0f25 100644 --- a/src/main/java/com/example/myongsick/domain/scrap/service/ScrapServiceImpl.java +++ b/src/main/java/com/example/myongsick/domain/scrap/service/ScrapServiceImpl.java @@ -10,6 +10,7 @@ import com.example.myongsick.domain.scrap.exception.NotFoundScrapException; import com.example.myongsick.domain.scrap.exception.NotFoundStoreException; import com.example.myongsick.domain.scrap.repository.ScrapRepository; +import com.example.myongsick.domain.scrap.repository.ScrapRepositoryCustom; import com.example.myongsick.domain.scrap.repository.StoreRepository; import com.example.myongsick.domain.user.entity.User; import com.example.myongsick.domain.user.exception.NotFoundUserException; @@ -39,6 +40,7 @@ public class ScrapServiceImpl implements ScrapService{ private final UserRepository userRepository; private final ScrapRepository scrapRepository; private final StoreRepository storeRepository; + private final ScrapRepositoryCustom scrapRepositoryCustom; @Value("${kakao.rest-key}") private String kakaoRestKey; @@ -80,7 +82,8 @@ public void deleteScrap(Long scrapId) { @Override public Page getScrapCount(String campus, Pageable pageable) { - return scrapRepository.findAllCustom(campus, pageable).map(ScrapCountResponse::toDto); +// return scrapRepositoryCustom.findAllCustom(campus, pageable).map(ScrapCountResponse::toDto); + return scrapRepositoryCustom.findAllByCampusWithPaging(campus, pageable); } @Transactional @@ -113,6 +116,7 @@ public void updateStore() { @Override public ScrapCountResponse getStoreOne(Long storeId) { - return storeRepository.findByIdCustom(storeId).map(ScrapCountResponse::toDto).orElseThrow(NotFoundStoreException::new); +// return storeRepository.findByIdCustom(storeId).map(ScrapCountResponse::toDto).orElseThrow(NotFoundStoreException::new); + return scrapRepositoryCustom.findByIdCustom(storeId).orElseThrow(NotFoundStoreException::new); } } diff --git a/src/main/java/com/example/myongsick/global/config/QueryDslConfig.java b/src/main/java/com/example/myongsick/global/config/QueryDslConfig.java new file mode 100644 index 0000000..a61d081 --- /dev/null +++ b/src/main/java/com/example/myongsick/global/config/QueryDslConfig.java @@ -0,0 +1,19 @@ +package com.example.myongsick.global.config; + +import com.querydsl.jpa.impl.JPAQueryFactory; +import javax.persistence.EntityManager; +import javax.persistence.PersistenceContext; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class QueryDslConfig { + + @PersistenceContext + private EntityManager em; + + @Bean + public JPAQueryFactory jpaQueryFactory(EntityManager em) { + return new JPAQueryFactory(em); + } +}