Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package com.example.customerservice.actor.controller;

import com.example.customerservice.actor.dto.response.AppearancePageResponse;
import com.example.customerservice.actor.service.AppearanceService;
import jakarta.validation.constraints.PositiveOrZero;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@RequestMapping("/api/appearance")
public class AppearanceController {
private final AppearanceService appearanceService;

@GetMapping
public ResponseEntity<AppearancePageResponse> getAppearance(
@PositiveOrZero @RequestParam(defaultValue = "0") int page,
@PositiveOrZero @RequestParam(defaultValue = "10") int size,
@RequestParam(value = "actor") String actor

){
AppearancePageResponse response = appearanceService.getAppearanceByName(actor, PageRequest.of(page, size));
return ResponseEntity.ok(response);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package com.example.customerservice.actor.dto.response;

import lombok.Builder;
import lombok.Getter;

import java.util.List;

@Builder
@Getter
public class AppearancePageResponse {
PageableResponse pageable;
List<AppearanceResponse> content;

public static AppearancePageResponse of(PageableResponse pageable, List<AppearanceResponse> content) {
return AppearancePageResponse.builder()
.pageable(pageable)
.content(content)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package com.example.customerservice.actor.dto.response;

import com.example.customerservice.contents.entity.Contents;
import lombok.Builder;
import lombok.Getter;

@Builder
@Getter
public class AppearanceResponse {
private Long contentId;
private String category;
private String title;
private String writer;

public static AppearanceResponse fromContent(Contents contents) {
return AppearanceResponse.builder()
.contentId(contents.getContentId())
.category(contents.getCategory())
.title(contents.getTitle())
.writer(contents.getWriter())
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
package com.example.customerservice.actor.dto.response;

import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Builder;
import lombok.Getter;
import org.springframework.data.domain.Pageable;

import static io.swagger.v3.oas.annotations.media.Schema.RequiredMode.REQUIRED;

@Builder
@Getter
public class PageableResponse {
@Schema(
defaultValue = "0",
description = "페이지 인덱스로, 0부터 시작합니다. 별도의 값 없이 요청 시, 0으로 설정됩니다.",
requiredMode = REQUIRED
)
private int page;

@Schema(
defaultValue = "10",
description = "페이지 내 최대 응답 개수입니다. 별도의 값 없이 요청 시, 10으로 설정됩니다.",
requiredMode = REQUIRED
)
private int size;

@Schema(
defaultValue = "3",
description = "전체 페이지 수 입니다.",
requiredMode = REQUIRED
)
private int totalPages;

@Schema(
defaultValue = "30",
description = "전체 요소 개수 입니다.",
requiredMode = REQUIRED
)
private int totalElements;

@Schema(
defaultValue = "false",
description = "현재 응답하는 페이지가 마지막 일 시, true로 설정됩니다.",
requiredMode = REQUIRED
)
private boolean isEnd;

public static PageableResponse of(Pageable pageable, int totalElementsSize) {
int totalPageSize = (int) Math.ceil((double) totalElementsSize / pageable.getPageSize());
boolean isEnd = pageable.getPageNumber() + 1 >= totalPageSize;
return PageableResponse.builder()
.page(pageable.getPageNumber())
.size(pageable.getPageSize())
.totalPages(totalPageSize)
.totalElements(totalElementsSize)
.isEnd(isEnd)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
package com.example.customerservice.actor.service;

import com.example.customerservice.actor.dto.response.AppearancePageResponse;
import com.example.customerservice.actor.dto.response.AppearanceResponse;
import com.example.customerservice.actor.dto.response.PageableResponse;
import com.example.customerservice.actor.entity.Actor;
import com.example.customerservice.actor.repository.ActorRepository;
import com.example.customerservice.contents.entity.Contents;
import com.example.customerservice.contents.repository.ContentsRepository;
import lombok.RequiredArgsConstructor;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;

@Service
@RequiredArgsConstructor
public class AppearanceService {
private final ActorRepository actorRepository;
private final ContentsRepository contentsRepository;

@Transactional(readOnly = true)
public AppearancePageResponse getAppearanceByName(String actorName, Pageable pageable) {
// 배우 이름으로 배우 조회
Actor actor = actorRepository.findByActorName(actorName)
.orElseThrow(() -> new RuntimeException("Actor not found"));

// 배우 출연작으로 총 작품 수 작품 조회
int totalSize = actor.getActorAppearances().size();

// 페이징을 위해 limit와 offset을 적용해서 조회
List<Contents> contentsByActorName = contentsRepository.findContentsByActorName(
actorName, pageable.getPageSize(), pageable.getOffset());

// 작품을 페이징 형식에 맞게 교체
List<AppearanceResponse> appearanceResponses = new ArrayList<>();
for (Contents content : contentsByActorName) {
appearanceResponses.add(AppearanceResponse.fromContent(content));
}
PageableResponse pageableResponse = PageableResponse.of(pageable, totalSize);

// 리턴할 객체 빌드
return AppearancePageResponse.of(pageableResponse, appearanceResponses);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,33 @@
import com.example.customerservice.contents.entity.Contents;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import java.util.List;

public interface ContentsRepository extends JpaRepository<Contents, Long> {
@Query("SELECT CONCAT(c.title, '|', c.writer) FROM Contents c")
List<String> findAllTitlesAndWriters();
@Query("SELECT CONCAT(c.title, '|', c.writer) FROM Contents c")
List<String> findAllTitlesAndWriters();

boolean existsByTitle(String title);
boolean existsByTitle(String title);

@Query(value = """
SELECT
*
FROM
actor a
JOIN
actor_appearances aa ON a.actor_id = aa.actor_id
JOIN
contents c ON aa.contents_id = c.content_id
WHERE
a.actor_name = :actorName
ORDER BY
c.content_id ASC
LIMIT :limit OFFSET :offset
""", nativeQuery = true)
List<Contents> findContentsByActorName(
@Param("actorName") String actorName,
@Param("limit") int limit,
@Param("offset") long offset);
}
Loading