From b17a8a310bc66b6510cb7e7ba786ea1db28a94fb Mon Sep 17 00:00:00 2001 From: Dong Seok Lee Date: Sun, 7 Jan 2024 16:17:13 +0900 Subject: [PATCH] =?UTF-8?q?[fix]=20refactor.=20=EC=95=8C=EC=BD=94=EC=98=AC?= =?UTF-8?q?=ED=83=80=EC=9E=85=EC=9C=BC=EB=A1=9C=20=EC=88=A0=EC=A0=95?= =?UTF-8?q?=EB=B3=B4=20=EC=A1=B0=ED=9A=8C=20=EA=B8=B0=EB=8A=A5=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../bside_311/component/AlcoholManager.java | 25 +++++ .../controller/AlcoholController.java | 9 +- .../bside_311/dto/AlcoholSearchCondition.java | 2 + .../repository/AlcoholRepositoryImpl.java | 18 ++-- .../bside_311/service/AlcoholService.java | 29 ++---- .../controller/AlcoholControllerTest.java | 20 ++++ .../repository/AlcoholRepositoryTest.java | 92 +++++++++++++++++++ .../repository/PostRepositoryTest.java | 8 +- .../repository/UserFollowRepositoryTest.java | 3 - .../repository/UserRepositoryTest.java | 8 +- 10 files changed, 172 insertions(+), 42 deletions(-) create mode 100644 server/src/test/java/com/bside/bside_311/repository/AlcoholRepositoryTest.java diff --git a/server/src/main/java/com/bside/bside_311/component/AlcoholManager.java b/server/src/main/java/com/bside/bside_311/component/AlcoholManager.java index 3666afa..f060bc7 100644 --- a/server/src/main/java/com/bside/bside_311/component/AlcoholManager.java +++ b/server/src/main/java/com/bside/bside_311/component/AlcoholManager.java @@ -1,17 +1,24 @@ package com.bside.bside_311.component; +import com.bside.bside_311.dto.AlcoholSearchCondition; import com.bside.bside_311.entity.Alcohol; +import com.bside.bside_311.entity.AlcoholType; import com.bside.bside_311.entity.Post; import com.bside.bside_311.entity.PostAlcohol; import com.bside.bside_311.entity.YesOrNo; import com.bside.bside_311.repository.AlcoholRepository; +import com.bside.bside_311.repository.AlcoholTypeRepository; import lombok.RequiredArgsConstructor; +import org.apache.commons.lang3.ObjectUtils; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; import org.springframework.stereotype.Component; @Component @RequiredArgsConstructor public class AlcoholManager { private final AlcoholRepository alcoholRepository; + private final AlcoholTypeRepository alcoholTypeRepository; public void connectAlcoholWithPost(Long alcoholNo, String alcoholFeature, Post post) { Alcohol alcohol = alcoholRepository.findByIdAndDelYnIs(alcoholNo, YesOrNo.N).orElseThrow( @@ -20,4 +27,22 @@ public void connectAlcoholWithPost(Long alcoholNo, String alcoholFeature, Post p post.addPostAlcohol(postAlcohol); alcohol.addPostAlcohol(postAlcohol); } + + public Page searchAlcohol(Pageable pageable, String searchKeyword, + Long alcoholType) { + if (ObjectUtils.isNotEmpty(alcoholType)) { + AlcoholType alcoholType1 = alcoholTypeRepository.findByIdAndDelYnIs(alcoholType, YesOrNo.N) + .orElseThrow( + () -> new IllegalArgumentException( + "술 종류가 존재하지 않습니다.")); + } + // 술 종류 fetch join + return alcoholRepository.searchAlcoholPage(AlcoholSearchCondition.builder() + .searchKeyword( + searchKeyword) + .alcoholType( + alcoholType) + .build(), + pageable); + } } diff --git a/server/src/main/java/com/bside/bside_311/controller/AlcoholController.java b/server/src/main/java/com/bside/bside_311/controller/AlcoholController.java index b9ed0de..4e5689b 100644 --- a/server/src/main/java/com/bside/bside_311/controller/AlcoholController.java +++ b/server/src/main/java/com/bside/bside_311/controller/AlcoholController.java @@ -14,6 +14,7 @@ import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.tags.Tag; import jakarta.validation.Valid; +import jakarta.validation.constraints.Positive; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.data.domain.Page; @@ -102,9 +103,13 @@ public Page getAlcoholV2( Pageable pageable, @RequestParam(required = false, name = "searchKeyword") @Schema(description = "키워드", example = "키워드") - String searchKeyword) { + String searchKeyword, + @RequestParam(required = false, name = "alcoholType") + @Schema(description = "술 타입(선택)", example = "1") + @Positive(message = "술 타입은 1이상의 숫자만 가능합니다.") + Long alcoholType) { log.info(">>> AlcoholController.getAlcohol"); - return alcoholService.getAlcoholV2(pageable, searchKeyword); + return alcoholService.getAlcoholV2(pageable, searchKeyword, alcoholType); } @Operation(summary = "[o]술 상세 조회", description = "술 상세 조회 API") diff --git a/server/src/main/java/com/bside/bside_311/dto/AlcoholSearchCondition.java b/server/src/main/java/com/bside/bside_311/dto/AlcoholSearchCondition.java index 3460026..c897f61 100644 --- a/server/src/main/java/com/bside/bside_311/dto/AlcoholSearchCondition.java +++ b/server/src/main/java/com/bside/bside_311/dto/AlcoholSearchCondition.java @@ -13,4 +13,6 @@ public class AlcoholSearchCondition { @Schema(description = "키워드", example = "키워드") String searchKeyword; + @Schema(description = "술 종류 PK", example = "1") + Long alcoholType; } diff --git a/server/src/main/java/com/bside/bside_311/repository/AlcoholRepositoryImpl.java b/server/src/main/java/com/bside/bside_311/repository/AlcoholRepositoryImpl.java index 0e2c782..685c0ad 100644 --- a/server/src/main/java/com/bside/bside_311/repository/AlcoholRepositoryImpl.java +++ b/server/src/main/java/com/bside/bside_311/repository/AlcoholRepositoryImpl.java @@ -2,27 +2,21 @@ import com.bside.bside_311.dto.AlcoholSearchCondition; import com.bside.bside_311.entity.Alcohol; -import com.bside.bside_311.entity.Post; -import com.bside.bside_311.entity.QAlcohol; -import com.bside.bside_311.entity.QAlcoholType; -import com.bside.bside_311.entity.QUser; import com.bside.bside_311.entity.YesOrNo; import com.bside.bside_311.repository.support.Querydsl4RepositorySupport; import com.querydsl.core.types.dsl.BooleanExpression; import com.querydsl.jpa.impl.JPAQuery; import com.querydsl.jpa.impl.JPAQueryFactory; import jakarta.persistence.EntityManager; +import org.apache.commons.lang3.ObjectUtils; import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; -import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.util.StringUtils; -import java.util.Optional; import java.util.function.Function; import static com.bside.bside_311.entity.QAlcohol.alcohol; import static com.bside.bside_311.entity.QAlcoholType.alcoholType; -import static com.bside.bside_311.entity.QPost.post; public class AlcoholRepositoryImpl extends Querydsl4RepositorySupport implements AlcoholRepositoryCustom { @@ -39,14 +33,20 @@ public Page searchAlcoholPage(AlcoholSearchCondition condition, Pageabl query -> query.select(alcohol) .from(alcohol) .leftJoin(alcoholType).on((alcohol.alcoholType.eq(alcoholType)) - .and(alcohol.delYn.eq(YesOrNo.N)) - .and(alcoholType.delYn.eq(YesOrNo.N))) + .and(alcohol.delYn.eq(YesOrNo.N)) + .and(alcoholType.delYn.eq(YesOrNo.N))) .where(contentLike(condition.getSearchKeyword()), + alcoholTypeIs(condition.getAlcoholType()), notDeleted()); return applyPagination(pageable, jpaQueryFactoryJPAQueryFunction ); } + private BooleanExpression alcoholTypeIs(Long alcoholType) { + return ObjectUtils.isNotEmpty(alcoholType) ? alcohol.alcoholType.id.eq(alcoholType) : + null; + } + private BooleanExpression contentLike(String searchKeyword) { return StringUtils.hasText(searchKeyword) ? alcohol.name.contains(searchKeyword) : null; } diff --git a/server/src/main/java/com/bside/bside_311/service/AlcoholService.java b/server/src/main/java/com/bside/bside_311/service/AlcoholService.java index cfbdfc4..4a2cf7c 100644 --- a/server/src/main/java/com/bside/bside_311/service/AlcoholService.java +++ b/server/src/main/java/com/bside/bside_311/service/AlcoholService.java @@ -1,9 +1,10 @@ package com.bside.bside_311.service; +import com.bside.bside_311.component.AlcoholManager; +import com.bside.bside_311.component.AttachManager; import com.bside.bside_311.dto.AddAlcoholRequestDto; import com.bside.bside_311.dto.AddAlcoholResponseDto; import com.bside.bside_311.dto.AlcoholResponseDto; -import com.bside.bside_311.dto.AlcoholSearchCondition; import com.bside.bside_311.dto.AttachDto; import com.bside.bside_311.dto.EditAlcoholRequestDto; import com.bside.bside_311.dto.GetAlcoholResponseDto; @@ -14,7 +15,6 @@ import com.bside.bside_311.entity.AlcoholNickname; import com.bside.bside_311.entity.AlcoholTag; import com.bside.bside_311.entity.AlcoholType; -import com.bside.bside_311.entity.Attach; import com.bside.bside_311.entity.AttachType; import com.bside.bside_311.entity.Tag; import com.bside.bside_311.entity.YesOrNo; @@ -45,6 +45,8 @@ @RequiredArgsConstructor @Transactional public class AlcoholService { + private final AlcoholManager alcoholManager; + private final AttachManager attachManager; private final AlcoholRepository alcoholRepository; private final TagService tagService; private final TagRepository tagRepository; @@ -189,25 +191,12 @@ public GetAlcoholResponseDto getAlcohol(Long page, Long size, String orderColumn return GetAlcoholResponseDto.of(alcoholResponseDtos, alcoholsCount); } - public Page getAlcoholV2(Pageable pageable, String searchKeyword) { - // 술 종류 fetch join - Page alcohols = alcoholRepository.searchAlcoholPage(AlcoholSearchCondition.builder() - .searchKeyword( - searchKeyword) - .build(), - pageable); + public Page getAlcoholV2(Pageable pageable, String searchKeyword, + Long alcoholType) { + Page alcohols = alcoholManager.searchAlcohol(pageable, searchKeyword, alcoholType); List alcoholNos = alcohols.stream().map(Alcohol::getId).toList(); - List alcoholAttachList = - attachRepository.findByRefNoInAndAttachTypeIsAndDelYnIs(alcoholNos, AttachType.ALCOHOL, - YesOrNo.N); - Map> aToAMap = new HashMap<>(); - for (Attach attach : alcoholAttachList) { - if (!aToAMap.containsKey(attach.getRefNo())) { - aToAMap.put(attach.getRefNo(), new ArrayList<>()); - } - List attachDtos = aToAMap.get(attach.getRefNo()); - attachDtos.add(AttachDto.of(attach)); - } + Map> aToAMap = attachManager.getAttachInfoMapBykeysAndType(alcoholNos, + AttachType.ALCOHOL); return alcohols.map(alcohol -> { List attachDtos = aToAMap.getOrDefault(alcohol.getId(), new ArrayList<>()); return AlcoholResponseDto.of(alcohol, attachDtos); diff --git a/server/src/test/java/com/bside/bside_311/controller/AlcoholControllerTest.java b/server/src/test/java/com/bside/bside_311/controller/AlcoholControllerTest.java index e0bfffc..30437a2 100644 --- a/server/src/test/java/com/bside/bside_311/controller/AlcoholControllerTest.java +++ b/server/src/test/java/com/bside/bside_311/controller/AlcoholControllerTest.java @@ -27,4 +27,24 @@ void getAlcoholTypeList() throws Exception { //then } + + @Test + void getAlcoholV2_success() throws Exception { + // given + // when + // then + String queryParameter = "?alcoholType=1&searchKeyword=소주"; + mockMvc.perform(get(String.format("/alcohols/v2%s", queryParameter))) + .andExpect(status().isOk()); + } + + @Test + void getAlcoholV2_fail() throws Exception { + // given + // when + // then + String queryParameter = "?alcoholType=asdf&searchKeyword=소주"; + mockMvc.perform(get(String.format("/alcohols/v2%s", queryParameter))) + .andExpect(status().is4xxClientError()); + } } \ No newline at end of file diff --git a/server/src/test/java/com/bside/bside_311/repository/AlcoholRepositoryTest.java b/server/src/test/java/com/bside/bside_311/repository/AlcoholRepositoryTest.java new file mode 100644 index 0000000..47a8a6f --- /dev/null +++ b/server/src/test/java/com/bside/bside_311/repository/AlcoholRepositoryTest.java @@ -0,0 +1,92 @@ +package com.bside.bside_311.repository; + +import com.bside.bside_311.dto.AlcoholSearchCondition; +import com.bside.bside_311.entity.Alcohol; +import com.bside.bside_311.entity.AlcoholType; +import jakarta.persistence.EntityManager; +import jakarta.persistence.PersistenceContext; +import org.assertj.core.api.Assertions; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; + +import java.util.ArrayList; +import java.util.List; + +@DataJpaTest +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) +class AlcoholRepositoryTest { + @Autowired + AlcoholTypeRepository alcoholTypeRepository; + + @Autowired + AlcoholRepository alcoholRepository; + + @PersistenceContext + private EntityManager em; + + @Test + void findByAlcoholType() { + //given 술타입이 3종류 있다. + // 그리고 술은 한 8개 있음. + // 그중에 3개 정도가 내가 조회하려는 타입임. + //when 술타입으로 조회하면 + //then 3개가 조회됨. + List alcoholTypeList = dataInitAlcoholType(); + List alcoholList = dataInitAlcohol(alcoholTypeList); + + // when. + Page byAlcoholType = + alcoholRepository.searchAlcoholPage(AlcoholSearchCondition.builder() + .alcoholType( + alcoholTypeList.get( + 0).getId()) + .build(), + PageRequest.of(0, 10)); + + // then. + List content = byAlcoholType.getContent(); + content.forEach(System.out::println); + Assertions.assertThat(content.size()).isEqualTo(4); + + + } + + private List dataInitAlcohol(List alcoholTypeList) { + List alcoholList = new ArrayList<>(); + for (int i = 0; i < 10; i++) { + // 술 10개 만들기 + // alcoholTypeList 기준. + // 0idx : 4 + // 1idx : 3 + // 2idx : 3 + alcoholList.add( + Alcohol.builder().name("술" + i).description("설명이다" + i) + .alcoholType(alcoholTypeList.get(i % 3)).build()); + } + alcoholRepository.saveAll(alcoholList); + em.flush(); + em.clear(); + return alcoholList; + } + + private List dataInitAlcoholType() { + List alcoholTypeList = new ArrayList<>(); + for (int i = 0; i < 3; i++) { + // 알코올 타입 3개 만들기 + alcoholTypeList.add( + AlcoholType.builder().name("맥주" + i).description("설명이다" + i).displayOrder(i + 1L) + .build()); + } + alcoholTypeRepository.saveAll(alcoholTypeList); + em.flush(); + em.clear(); + + + return alcoholTypeList; + } + +} \ No newline at end of file diff --git a/server/src/test/java/com/bside/bside_311/repository/PostRepositoryTest.java b/server/src/test/java/com/bside/bside_311/repository/PostRepositoryTest.java index 1b7d5df..1558724 100644 --- a/server/src/test/java/com/bside/bside_311/repository/PostRepositoryTest.java +++ b/server/src/test/java/com/bside/bside_311/repository/PostRepositoryTest.java @@ -8,15 +8,15 @@ import org.assertj.core.api.Assertions; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.data.domain.Page; -import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; -@SpringBootTest -@Transactional +@DataJpaTest +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) //@Rollback(false) class PostRepositoryTest { @Autowired diff --git a/server/src/test/java/com/bside/bside_311/repository/UserFollowRepositoryTest.java b/server/src/test/java/com/bside/bside_311/repository/UserFollowRepositoryTest.java index af06d28..1400121 100644 --- a/server/src/test/java/com/bside/bside_311/repository/UserFollowRepositoryTest.java +++ b/server/src/test/java/com/bside/bside_311/repository/UserFollowRepositoryTest.java @@ -3,15 +3,12 @@ import com.bside.bside_311.entity.UserFollow; import com.bside.bside_311.entity.YesOrNo; import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; -import org.springframework.test.context.junit.jupiter.SpringExtension; import java.util.List; -@ExtendWith(SpringExtension.class) @DataJpaTest @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) class UserFollowRepositoryTest { diff --git a/server/src/test/java/com/bside/bside_311/repository/UserRepositoryTest.java b/server/src/test/java/com/bside/bside_311/repository/UserRepositoryTest.java index 29924a2..2e38c50 100644 --- a/server/src/test/java/com/bside/bside_311/repository/UserRepositoryTest.java +++ b/server/src/test/java/com/bside/bside_311/repository/UserRepositoryTest.java @@ -10,18 +10,18 @@ import org.junit.jupiter.api.Test; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Value; -import org.springframework.boot.test.context.SpringBootTest; +import org.springframework.boot.test.autoconfigure.jdbc.AutoConfigureTestDatabase; +import org.springframework.boot.test.autoconfigure.orm.jpa.DataJpaTest; import org.springframework.data.domain.Page; import org.springframework.data.domain.PageRequest; import org.springframework.data.domain.Sort; -import org.springframework.transaction.annotation.Transactional; import java.util.ArrayList; import java.util.List; import java.util.Optional; -@SpringBootTest -@Transactional +@DataJpaTest +@AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE) //@Rollback(false) class UserRepositoryTest { @Autowired