Skip to content

Commit aa496f6

Browse files
authored
[Refactor]칵테일 조회 조건 추가, cocktail Story 관련 cocktailPreview 추가 (#247)
* fix : bugs of testCase, init data * fix : bug * refactor : add cocktailPreview field in cocktailSearchResponseDto * refactor : add getCocktails conditions
1 parent a9ccd1a commit aa496f6

File tree

4 files changed

+104
-70
lines changed

4 files changed

+104
-70
lines changed

src/main/java/com/back/domain/cocktail/controller/CocktailController.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,17 +31,20 @@ public RsData<CocktailDetailResponseDto> getCocktailDetailById(@PathVariable lon
3131
return RsData.successOf(cocktailDetailResponseDto);
3232
}
3333

34+
// @param lastValue 다음 페이지에서 이 값보다 작은 항목만 가져오기 위해 사용
3435
// @param lastId 마지막으로 가져온 칵테일 ID (첫 요청 null 가능)
3536
// @param size 가져올 데이터 개수 (기본값 DEFAULT_SIZE)
3637
// @return RsData 형태의 칵테일 요약 정보 리스트
3738
@GetMapping
3839
@Transactional
3940
@Operation(summary = "칵테일 다건 조회")
4041
public RsData<List<CocktailSummaryResponseDto>> getCocktails(
42+
@RequestParam(value = "lastValue", required = false) Long lastValue,
4143
@RequestParam(value = "lastId", required = false) Long lastId,
42-
@RequestParam(value = "size", required = false) Integer size
44+
@RequestParam(value = "size", required = false) Integer size,
45+
@RequestParam(value = "sortBy", required = false, defaultValue = "recent") String sortBy
4346
) {
44-
List<CocktailSummaryResponseDto> cocktails = cocktailService.getCocktails(lastId, size);
47+
List<CocktailSummaryResponseDto> cocktails = cocktailService.getCocktails(lastValue, lastId, size, sortBy);
4548
return RsData.successOf(cocktails);
4649
}
4750

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,34 @@
11
package com.back.domain.cocktail.dto;
22

3-
import lombok.Getter;
4-
import lombok.NoArgsConstructor;
5-
import lombok.Setter;
3+
import com.back.domain.cocktail.entity.Cocktail;
64

7-
@Getter
8-
@Setter
9-
@NoArgsConstructor
10-
public class CocktailSearchResponseDto {
5+
public record CocktailSearchResponseDto (
116

12-
private long cocktailId;
13-
private String cocktailName;
14-
private String cocktailNameKo;
15-
private String alcoholStrength;
16-
private String cocktailType;
17-
private String alcoholBaseType;
18-
private String cocktailImgUrl;
19-
private String cocktailStory;
7+
Long cocktailId,
8+
String cocktailName,
9+
String cocktailNameKo,
10+
String alcoholStrength,
11+
String cocktailType,
12+
String alcoholBaseType,
13+
String cocktailImgUrl,
14+
String cocktailStory,
15+
String cocktailPreview
16+
){
17+
public static CocktailSearchResponseDto from(Cocktail cocktail){
18+
String preview =cocktail.getCocktailStory().length() >80 ?
19+
cocktail.getCocktailStory().substring(0,80)+"..."
20+
: cocktail.getCocktailStory();
2021

21-
public CocktailSearchResponseDto(long cocktailId, String cocktailName, String cocktailNameKo,
22-
String alcoholStrength, String cocktailType,
23-
String alcoholBaseType, String cocktailImgUrl,
24-
String cocktailStory) {
25-
this.cocktailId = cocktailId;
26-
this.cocktailName = cocktailName;
27-
this.cocktailNameKo = cocktailNameKo;
28-
this.alcoholStrength = alcoholStrength;
29-
this.cocktailType = cocktailType;
30-
this.alcoholBaseType = alcoholBaseType;
31-
this.cocktailImgUrl = cocktailImgUrl;
32-
this.cocktailStory = cocktailStory;
22+
return new CocktailSearchResponseDto(
23+
cocktail.getId(),
24+
cocktail.getCocktailName(),
25+
cocktail.getCocktailNameKo(),
26+
cocktail.getAlcoholStrength().getDescription(),
27+
cocktail.getCocktailType().getDescription(),
28+
cocktail.getAlcoholBaseType().getDescription(),
29+
cocktail.getCocktailImgUrl(),
30+
cocktail.getCocktailStory(),
31+
preview
32+
);
3333
}
3434
}

src/main/java/com/back/domain/cocktail/repository/CocktailRepository.java

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,14 +16,54 @@
1616
@Repository
1717
public interface CocktailRepository extends JpaRepository<Cocktail, Long> {
1818

19-
// 첫 요청 → 최신순(내림차순)으로 정렬해서 가져오기
19+
// 전체조회 : 최신순
2020
List<Cocktail> findAllByOrderByIdDesc(Pageable pageable);
21-
22-
// 무한스크롤 → lastId보다 작은 ID들 가져오기
2321
List<Cocktail> findByIdLessThanOrderByIdDesc(Long lastId, Pageable pageable);
2422

25-
List<Cocktail> findByCocktailNameContainingIgnoreCaseOrIngredientContainingIgnoreCase(String cocktailName, String ingredient);
23+
// 전체 조회: keepsCount 기준 내림차순
24+
@Query("""
25+
SELECT c FROM Cocktail c
26+
LEFT JOIN MyBar m ON m.cocktail = c AND m.status = 'ACTIVE'
27+
GROUP BY c.id
28+
ORDER BY COUNT(m) DESC, c.id DESC
29+
""")
30+
List<Cocktail> findAllOrderByKeepCountDesc(Pageable pageable);
31+
32+
// 무한스크롤 조회: lastKeepCount 이하
33+
@Query("""
34+
SELECT c FROM Cocktail c
35+
LEFT JOIN MyBar m ON m.cocktail = c AND m.status = 'ACTIVE'
36+
GROUP BY c.id
37+
HAVING COUNT(m) < :lastKeepCount OR (COUNT(m) = :lastKeepCount AND c.id < :lastId)
38+
ORDER BY COUNT(m) DESC, c.id DESC
39+
""")
40+
List<Cocktail> findByKeepCountLessThanOrderByKeepCountDesc(
41+
@Param("lastKeepCount") Long lastKeepCount,
42+
@Param("lastId") Long lastId,
43+
Pageable pageable
44+
);
45+
46+
// 댓글순
47+
@Query("SELECT c FROM Cocktail c " +
48+
"LEFT JOIN CocktailComment cm ON cm.cocktail = c " +
49+
"GROUP BY c.id " +
50+
"ORDER BY COUNT(cm) DESC, c.id DESC")
51+
List<Cocktail> findAllOrderByCommentsCountDesc(Pageable pageable);
52+
53+
@Query("""
54+
SELECT c FROM Cocktail c
55+
LEFT JOIN CocktailComment cm ON cm.cocktail = c
56+
GROUP BY c.id
57+
HAVING COUNT(cm) < :lastCommentsCount OR (COUNT(cm) = :lastCommentsCount AND c.id < :lastId)
58+
ORDER BY COUNT(cm) DESC, c.id DESC
59+
""")
60+
List<Cocktail> findByCommentsCountLessThanOrderByCommentsCountDesc(
61+
@Param("lastCommentsCount") Long lastCommentsCount,
62+
@Param("lastId") Long lastId,
63+
Pageable pageable
64+
);
2665

66+
//검색, 필터
2767
@Query("SELECT c FROM Cocktail c " +
2868
"WHERE (:keyword IS NULL OR :keyword = '' OR " +
2969
" LOWER(c.cocktailName) LIKE LOWER(CONCAT('%', :keyword, '%')) OR " +

src/main/java/com/back/domain/cocktail/service/CocktailService.java

Lines changed: 28 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -37,37 +37,41 @@ public Cocktail getCocktailById(Long id) {
3737
.orElseThrow(() -> new IllegalArgumentException("Cocktail not found. id=" + id));
3838
}
3939

40-
// 칵테일 무한스크롤 조회
4140
@Transactional(readOnly = true)
42-
public List<CocktailSummaryResponseDto> getCocktails(Long lastId, Integer size) { // 무한스크롤 조회, 클라이언트 쪽에서 lastId와 size 정보를 받음.(스크롤 이벤트)
41+
public List<CocktailSummaryResponseDto> getCocktails(Long lastValue, Long lastId, Integer size, String sortBy) {
4342
int fetchSize = (size != null) ? size : DEFAULT_SIZE;
44-
43+
Pageable pageable = PageRequest.of(0, fetchSize);
4544
List<Cocktail> cocktails;
46-
if (lastId == null) {
47-
// 첫 요청 → 최신 데이터부터
48-
cocktails = cocktailRepository.findAllByOrderByIdDesc(PageRequest.of(0, fetchSize));
49-
} else {
50-
// 무한스크롤 → 마지막 ID보다 작은 데이터 조회
51-
cocktails = cocktailRepository.findByIdLessThanOrderByIdDesc(lastId, PageRequest.of(0, fetchSize));
45+
46+
switch (sortBy != null ? sortBy.toLowerCase() : "") {
47+
case "keeps":
48+
cocktails = (lastValue == null)
49+
? cocktailRepository.findAllOrderByKeepCountDesc(pageable)
50+
: cocktailRepository.findByKeepCountLessThanOrderByKeepCountDesc(lastValue, lastId, pageable);
51+
break;
52+
case "comments":
53+
cocktails = (lastValue == null)
54+
? cocktailRepository.findAllOrderByCommentsCountDesc(pageable)
55+
: cocktailRepository.findByCommentsCountLessThanOrderByCommentsCountDesc(lastValue, lastId, pageable);
56+
break;
57+
default:
58+
cocktails = (lastValue == null)
59+
? cocktailRepository.findAllByOrderByIdDesc(pageable)
60+
: cocktailRepository.findByIdLessThanOrderByIdDesc(lastValue, pageable);
61+
break;
5262
}
63+
5364
return cocktails.stream()
54-
.map(c -> new CocktailSummaryResponseDto(c.getId(), c.getCocktailName(), c.getCocktailNameKo(), c.getCocktailImgUrl(), c.getAlcoholStrength().getDescription()))
65+
.map(c -> new CocktailSummaryResponseDto(
66+
c.getId(),
67+
c.getCocktailName(),
68+
c.getCocktailNameKo(),
69+
c.getCocktailImgUrl(),
70+
c.getAlcoholStrength().getDescription()
71+
))
5572
.collect(Collectors.toList());
5673
}
5774

58-
// 칵테일 검색기능
59-
@Transactional(readOnly = true)
60-
public List<Cocktail> cocktailSearch(String keyword) {
61-
// cockTailName, ingredient이 하나만 있을 수도 있고 둘 다 있을 수도 있음
62-
if (keyword == null || keyword.trim().isEmpty()) {
63-
// 아무 검색어 없으면 전체 반환 처리
64-
return cocktailRepository.findAll();
65-
} else {
66-
// 이름 또는 재료 둘 중 하나라도 매칭되면 결과 반환
67-
return cocktailRepository.findByCocktailNameContainingIgnoreCaseOrIngredientContainingIgnoreCase(keyword, keyword);
68-
}
69-
}
70-
7175
// 칵테일 검색,필터기능
7276
@Transactional(readOnly = true)
7377
public List<CocktailSearchResponseDto> searchAndFilter(CocktailSearchRequestDto cocktailSearchRequestDto) {
@@ -105,25 +109,12 @@ public List<CocktailSearchResponseDto> searchAndFilter(CocktailSearchRequestDto
105109

106110
//Cocktail 엔티티 → CocktailResponseDto 응답 DTO로 바꿔주는 과정
107111
List<CocktailSearchResponseDto> resultDtos = pageResult.stream()
108-
.map(c -> new CocktailSearchResponseDto(
109-
c.getId(),
110-
c.getCocktailName(),
111-
c.getCocktailNameKo(),
112-
c.getAlcoholStrength().getDescription(),
113-
c.getCocktailType().getDescription(),
114-
c.getAlcoholBaseType().getDescription(),
115-
c.getCocktailImgUrl(),
116-
c.getCocktailStory()
117-
))
112+
.map(CocktailSearchResponseDto::from)
118113
.collect(Collectors.toList());
119114

120115
return resultDtos;
121116
}
122117

123-
// private <T> List<T> nullIfEmpty(List<T> list) {
124-
// return CollectionUtils.isEmpty(list) ? null : list;
125-
// }
126-
127118
// 칵테일 상세조회
128119
@Transactional(readOnly = true)
129120
public CocktailDetailResponseDto getCocktailDetailById(Long cocktailId) {

0 commit comments

Comments
 (0)