-
Notifications
You must be signed in to change notification settings - Fork 0
feat(#362): 캠페인 태그 조회 api 추가 #368
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,44 @@ | ||
| package com.example.RealMatch.business.application.service; | ||
|
|
||
| import java.util.Arrays; | ||
| import java.util.List; | ||
|
|
||
| import org.springframework.stereotype.Service; | ||
| import org.springframework.transaction.annotation.Transactional; | ||
|
|
||
| import com.example.RealMatch.business.domain.enums.ContentTagSort; | ||
| import com.example.RealMatch.business.presentation.dto.response.TagContentSortResponse; | ||
| import com.example.RealMatch.tag.domain.entity.TagContent; | ||
| import com.example.RealMatch.tag.domain.repository.TagContentRepository; | ||
|
|
||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| @Service | ||
| @RequiredArgsConstructor | ||
| @Transactional(readOnly = true) | ||
| public class TagContentSortQueryService { | ||
|
|
||
| private final TagContentRepository tagContentRepository; | ||
|
|
||
| public List<TagContentSortResponse> getAllGroupedBySort() { | ||
|
|
||
| List<TagContent> allTags = tagContentRepository.findAll(); | ||
|
|
||
| return Arrays.stream(ContentTagSort.values()) | ||
| .map(sort -> { | ||
| List<TagContent> filtered = allTags.stream() | ||
| .filter(tag -> | ||
| tag.getTagType().name().equals(sort.name()) | ||
| ) | ||
| .toList(); | ||
|
|
||
| return TagContentSortResponse.from(sort, filtered); | ||
| }) | ||
| .toList(); | ||
| } | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,17 @@ | ||||||||||||||||||||||||||||||||||||||||
| package com.example.RealMatch.business.domain.enums; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| import lombok.Getter; | ||||||||||||||||||||||||||||||||||||||||
| import lombok.RequiredArgsConstructor; | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| @Getter | ||||||||||||||||||||||||||||||||||||||||
| @RequiredArgsConstructor | ||||||||||||||||||||||||||||||||||||||||
| public enum ContentTagSort { | ||||||||||||||||||||||||||||||||||||||||
| FORMAT("형식"), | ||||||||||||||||||||||||||||||||||||||||
| CATEGORY("종류"), | ||||||||||||||||||||||||||||||||||||||||
| TONE("톤"), | ||||||||||||||||||||||||||||||||||||||||
| INVOLVEMENT("관여도"), | ||||||||||||||||||||||||||||||||||||||||
| USAGE_RANGE("활용 범위"); | ||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| private final String korName; | ||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+8
to
+16
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 현재
참고: 아래 제안을 적용하려면 파일 상단에
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| package com.example.RealMatch.business.presentation.controller; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import org.springframework.web.bind.annotation.GetMapping; | ||
| import org.springframework.web.bind.annotation.RequestMapping; | ||
| import org.springframework.web.bind.annotation.RestController; | ||
|
|
||
| import com.example.RealMatch.business.application.service.TagContentSortQueryService; | ||
| import com.example.RealMatch.business.presentation.dto.response.TagContentSortResponse; | ||
|
|
||
| import io.swagger.v3.oas.annotations.Operation; | ||
| import io.swagger.v3.oas.annotations.tags.Tag; | ||
| import lombok.RequiredArgsConstructor; | ||
|
|
||
| @Tag(name = "Business-ContentTag", description = "비즈니스 캠페인 콘텐츠 태그") | ||
| @RestController | ||
| @RequiredArgsConstructor | ||
| @RequestMapping("/api/v1/tag-contents/sort") | ||
| public class TagContentSortController { | ||
|
|
||
| private final TagContentSortQueryService tagContentSortQueryService; | ||
|
|
||
| @Operation( | ||
| summary = "콘텐츠 태그 정렬 기준별 조회", | ||
| description = """ | ||
| 콘텐츠 태그를 정렬 기준(ContentTagSort)별로 그룹화하여 조회합니다. | ||
|
|
||
| [응답 구조] | ||
| - sort: 태그 정렬 기준 (FORMAT, CATEGORY, TONE, INVOLVEMENT, USAGE_RANGE) | ||
| - sortKorName: 정렬 기준 한글명 (형식, 종류, 톤, 관여도, 활용 범위) | ||
| - tags: 해당 정렬 기준에 속하는 태그 목록 | ||
| - id: 태그 ID | ||
| - name: 태그 한글명 | ||
| """ | ||
| ) | ||
| @GetMapping | ||
| public List<TagContentSortResponse> getAll() { | ||
| return tagContentSortQueryService.getAllGroupedBySort(); | ||
| } | ||
| } | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| package com.example.RealMatch.business.presentation.dto.response; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import lombok.AllArgsConstructor; | ||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| @AllArgsConstructor | ||
| public class CollaborationPageResponse { | ||
|
|
||
| private List<CollaborationResponse> contents; | ||
| private int page; | ||
| private int size; | ||
| private long totalElements; | ||
| private int totalPages; | ||
| private boolean hasNext; | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| package com.example.RealMatch.business.presentation.dto.response; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| import com.example.RealMatch.business.domain.enums.ContentTagSort; | ||
| import com.example.RealMatch.tag.domain.entity.TagContent; | ||
|
|
||
| import lombok.Builder; | ||
| import lombok.Getter; | ||
|
|
||
| @Getter | ||
| @Builder | ||
| public class TagContentSortResponse { | ||
|
|
||
| private ContentTagSort sort; | ||
| private String sortKorName; | ||
| private List<TagItemResponse> tags; | ||
|
|
||
| public static TagContentSortResponse from( | ||
| ContentTagSort sort, | ||
| List<TagContent> tagContents | ||
| ) { | ||
| return TagContentSortResponse.builder() | ||
| .sort(sort) | ||
| .sortKorName(sort.getKorName()) | ||
| .tags(tagContents.stream() | ||
| .map(tag -> new TagItemResponse( | ||
| tag.getId(), | ||
| tag.getKorName() | ||
| )) | ||
| .toList()) | ||
| .build(); | ||
| } | ||
| } | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| package com.example.RealMatch.business.presentation.dto.response; | ||
|
|
||
| public record TagItemResponse( | ||
| Long id, | ||
| String name | ||
| ) {} | ||
|
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
현재
tagContentRepository.findAll()을 호출하여 모든 태그를 메모리로 가져온 후,ContentTagType별로 그룹화하고 있습니다. 태그의 수가 많아질 경우, 대규모 컬렉션을 메모리에서 필터링하고 그룹화하는 것은 심각한 성능 저하를 유발할 수 있습니다.findAll()대신,ContentTagType별로 미리 그룹화된 태그를 반환하는 전용 쿼리 메서드를TagContentRepository에 추가하여 데이터베이스 계층에서 이 로직을 처리하는 것을 강력히 권장합니다. 이렇게 하면 메모리 사용량을 줄이고 데이터베이스의 효율적인 인덱싱을 활용하여 성능을 크게 향상시킬 수 있습니다.References
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
나중에 수정해볼게 태그 25개라 일단은 그냥 함