Skip to content

Commit ddbf06b

Browse files
authored
[feat] 칵테일 조회 및 검색 기능 구현 (#32)
* {feat} : domain * {fix}:Cocktail-Wishlist relation * fix : enums * fix : bug * feat : 조회기능, 조init data * fix : naming * feat : cocktailSearch * fix :bug
1 parent 36838e1 commit ddbf06b

File tree

12 files changed

+201
-58
lines changed

12 files changed

+201
-58
lines changed

.gitignore

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,4 +41,5 @@ db_dev.mv.db
4141
db_dev.trace.db
4242

4343
### Environment Variables ###
44-
.env
44+
.env
45+

src/main/java/com/back/domain/cocktail/dto/CocktailRequestDto.java

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

3-
import com.back.domain.cocktail.entity.Cocktail;
3+
import com.back.domain.cocktail.enums.AlcoholBaseType;
4+
import com.back.domain.cocktail.enums.AlcoholStrength;
5+
import com.back.domain.cocktail.enums.CocktailType;
46
import jakarta.validation.constraints.NotBlank;
57
import jakarta.validation.constraints.NotNull;
68
import lombok.Getter;
@@ -16,12 +18,12 @@ public class CocktailRequestDto {
1618
private String cocktailName;
1719

1820
@NotNull
19-
private Cocktail.AlcoholStrength alcoholStrength;
21+
private AlcoholStrength alcoholStrength;
2022

2123
private String cocktailStory;
22-
private Cocktail.CocktailType cocktailType;
24+
private CocktailType cocktailType;
25+
private AlcoholBaseType alcoholBaseType;
2326
private String ingredient;
2427
private String recipe;
25-
private String imageUrl;
26-
28+
private String cocktailImgUrl;
2729
}

src/main/java/com/back/domain/cocktail/dto/CocktailResponseDto.java

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

3-
import com.back.domain.cocktail.entity.Cocktail;
3+
import com.back.domain.cocktail.enums.AlcoholBaseType;
4+
import com.back.domain.cocktail.enums.AlcoholStrength;
5+
import com.back.domain.cocktail.enums.CocktailType;
46
import lombok.Getter;
57
import lombok.NoArgsConstructor;
68
import lombok.Setter;
@@ -14,12 +16,13 @@ public class CocktailResponseDto {
1416

1517
private long cocktailId;
1618
private String cocktailName;
17-
private Cocktail.AlcoholStrength alcoholStrength;
19+
private AlcoholStrength alcoholStrength;
1820
private String cocktailStory;
19-
private Cocktail.CocktailType cocktailType;
21+
private CocktailType cocktailType;
22+
private AlcoholBaseType alcoholBaseType;
2023
private String ingredient;
2124
private String recipe;
22-
private String imageUrl;
25+
private String cocktailImgUrl;
2326
private LocalDateTime createdAt;
2427
private LocalDateTime updatedAt;
2528

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
package com.back.domain.cocktail.dto;
2+
3+
import lombok.Getter;
4+
5+
@Getter
6+
public class CocktailSummaryDto {
7+
private Long cocktailId;
8+
private String cocktailName;
9+
private String cocktailImgUrl;
10+
11+
public CocktailSummaryDto(Long id, String name, String imageUrl) {
12+
this.cocktailId = id;
13+
this.cocktailName = name;
14+
this.cocktailImgUrl = imageUrl;
15+
}
16+
}

src/main/java/com/back/domain/cocktail/entity/Cocktail.java

Lines changed: 10 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
package com.back.domain.cocktail.entity;
22

3+
import com.back.domain.cocktail.enums.AlcoholBaseType;
4+
import com.back.domain.cocktail.enums.AlcoholStrength;
5+
import com.back.domain.cocktail.enums.CocktailType;
36
import jakarta.persistence.*;
4-
import lombok.Getter;
5-
import lombok.NoArgsConstructor;
6-
import lombok.Setter;
7+
import lombok.*;
78

89
import java.time.LocalDateTime;
910

@@ -13,6 +14,9 @@
1314
@Getter
1415
@Setter
1516
@NoArgsConstructor
17+
@AllArgsConstructor
18+
@Builder
19+
@ToString
1620
@Entity
1721
public class Cocktail {
1822
@Id
@@ -24,52 +28,19 @@ public class Cocktail {
2428
@Enumerated(EnumType.STRING)
2529
private AlcoholStrength alcoholStrength; // 칵테일 알콜 도수
2630

27-
public enum AlcoholStrength {
28-
NON_ALCOHOLIC("논알콜 (0%)"),
29-
WEAK("약한 도수 (1~5%)"),
30-
LIGHT("가벼운 도수 (6~15%)"),
31-
MEDIUM("중간 도수 (16~25%)"),
32-
STRONG("센 도수 (26~35%)"),
33-
VERY_STRONG("매우 센 도수 (36%~)");
34-
35-
private final String description;
36-
37-
AlcoholStrength(String description) {
38-
this.description = description;
39-
}
40-
41-
public String getDescription() {
42-
return description;
43-
}
44-
}
45-
4631
private String cocktailStory; // 칵테일 유래 등 이야기
4732

4833
@Enumerated(EnumType.STRING)
4934
private CocktailType cocktailType; // 칵테일 컵에 따른 분류
5035

51-
public enum CocktailType {
52-
SHORT("숏"),
53-
LONG("롱"),
54-
SHOOTER("슈터"),
55-
CLASSIC("클래식");
56-
57-
private final String description;
58-
59-
CocktailType(String description) {
60-
this.description = description;
61-
}
62-
63-
public String getDescription() {
64-
return description;
65-
}
66-
}
36+
@Enumerated(EnumType.STRING)
37+
private AlcoholBaseType alcoholBaseType; // 칵테일 베이스에 따른 분류
6738

6839
private String ingredient;
6940

7041
private String recipe;
7142

72-
private String imageUrl;
43+
private String cocktailImgUrl;
7344

7445
private LocalDateTime createdAt;
7546

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package com.back.domain.cocktail.enums;
2+
3+
public enum AlcoholBaseType {
4+
GIN("진"),
5+
BRANDY("브랜디"),
6+
RUM("럼"),
7+
VODKA("보드카"),
8+
LIQUEUR("리큐르"),
9+
WHISKY("위스키"),
10+
TEQUILA("데낄라"),
11+
WINE("와인"),
12+
OTHER("기타");
13+
14+
private final String description;
15+
16+
AlcoholBaseType(String description) {
17+
this.description = description;
18+
}
19+
public String getDescription() {
20+
return description;
21+
}
22+
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
package com.back.domain.cocktail.enums;
2+
3+
public enum AlcoholStrength {
4+
NON_ALCOHOLIC("논알콜 (0%)"),
5+
WEAK("약한 도수 (1~5%)"),
6+
LIGHT("가벼운 도수 (6~15%)"),
7+
MEDIUM("중간 도수 (16~25%)"),
8+
STRONG("센 도수 (26~35%)"),
9+
VERY_STRONG("매우 센 도수 (36%~)");
10+
11+
private final String description;
12+
13+
AlcoholStrength(String description) {
14+
this.description = description;
15+
}
16+
17+
public String getDescription() {
18+
return description;
19+
}
20+
21+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package com.back.domain.cocktail.enums;
2+
3+
public enum CocktailType {
4+
SHORT("숏"),
5+
LONG("롱"),
6+
SHOOTER("슈터"),
7+
CLASSIC("클래식");
8+
9+
private final String description;
10+
11+
CocktailType(String description) {
12+
this.description = description;
13+
}
14+
15+
public String getDescription() {
16+
return description;
17+
}
18+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,20 @@
11
package com.back.domain.cocktail.repository;
22

33
import com.back.domain.cocktail.entity.Cocktail;
4+
import org.springframework.data.domain.Pageable;
45
import org.springframework.data.jpa.repository.JpaRepository;
56
import org.springframework.stereotype.Repository;
67

8+
import java.util.List;
9+
710
@Repository
811
public interface CocktailRepository extends JpaRepository<Cocktail, Long> {
12+
13+
// 첫 요청 → 최신순(내림차순)으로 정렬해서 가져오기
14+
List<Cocktail> findAllByOrderByCocktailIdDesc(Pageable pageable);
15+
16+
// 무한스크롤 → lastId보다 작은 ID들 가져오기
17+
List<Cocktail> findByCocktailIdLessThanOrderByCocktailIdDesc(Long lastId, Pageable pageable);
18+
19+
List<Cocktail> findByCocktailNameContainingIgnoreCaseOrIngredientContainingIgnoreCase(String cocktailName, String ingredient);
920
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package com.back.domain.cocktail.service;
2+
3+
import com.back.domain.cocktail.dto.CocktailSummaryDto;
4+
import com.back.domain.cocktail.entity.Cocktail;
5+
import com.back.domain.cocktail.repository.CocktailRepository;
6+
import lombok.RequiredArgsConstructor;
7+
import org.springframework.data.domain.PageRequest;
8+
import org.springframework.stereotype.Service;
9+
import org.springframework.transaction.annotation.Transactional;
10+
import java.util.List;
11+
import java.util.stream.Collectors;
12+
13+
@Service
14+
@RequiredArgsConstructor
15+
public class CocktailService {
16+
17+
private final CocktailRepository cocktailRepository;
18+
19+
private static final int DEFAULT_SIZE = 20;
20+
21+
@Transactional(readOnly = true)
22+
public Cocktail getCocktailById(Long id) {
23+
return cocktailRepository.findById(id)
24+
.orElseThrow(() -> new IllegalArgumentException("User not found. id=" + id));
25+
}
26+
27+
// 칵테일 무한스크롤 조회
28+
@Transactional(readOnly = true)
29+
public List<CocktailSummaryDto> getCocktails(Long lastId, Integer size) { // 무한스크롤 조회, 클라이언트 쪽에서 lastId와 size 정보를 받음.(스크롤 이벤트)
30+
int fetchSize = (size != null) ? size : DEFAULT_SIZE;
31+
32+
List<Cocktail> cocktails;
33+
if (lastId == null) {
34+
// 첫 요청 → 최신 데이터부터
35+
cocktails = cocktailRepository.findAllByOrderByCocktailIdDesc(PageRequest.of(0, fetchSize));
36+
} else {
37+
// 무한스크롤 → 마지막 ID보다 작은 데이터 조회
38+
cocktails = cocktailRepository.findByCocktailIdLessThanOrderByCocktailIdDesc(lastId, PageRequest.of(0, fetchSize));
39+
}
40+
41+
return cocktails.stream()
42+
.map(c -> new CocktailSummaryDto(c.getCocktailId(), c.getCocktailName(), c.getCocktailImgUrl()))
43+
.collect(Collectors.toList());
44+
}
45+
46+
// 칵테일 검색기능
47+
public List<Cocktail> cocktailSearch(String keyword) {
48+
// cockTailName, ingredient이 하나만 있을 수도 있고 둘 다 있을 수도 있음
49+
if (keyword == null || keyword.trim().isEmpty()) {
50+
// 아무 검색어 없으면 전체 반환 처리
51+
return cocktailRepository.findAll();
52+
} else {
53+
// 이름 또는 재료 둘 중 하나라도 매칭되면 결과 반환
54+
return cocktailRepository.findByCocktailNameContainingIgnoreCaseOrIngredientContainingIgnoreCase(keyword, keyword);
55+
}
56+
}
57+
}

0 commit comments

Comments
 (0)