diff --git a/apps/api-admin/src/main/java/com/ott/api_admin/series/controller/BackOfficeSeriesApi.java b/apps/api-admin/src/main/java/com/ott/api_admin/series/controller/BackOfficeSeriesApi.java index 1c4b0e5..c535e77 100644 --- a/apps/api-admin/src/main/java/com/ott/api_admin/series/controller/BackOfficeSeriesApi.java +++ b/apps/api-admin/src/main/java/com/ott/api_admin/series/controller/BackOfficeSeriesApi.java @@ -61,6 +61,6 @@ ResponseEntity>> getSeries( ) }) ResponseEntity> getSeriesDetail( - @Parameter(description = "시리즈 ID", required = true, example = "1") @PathVariable Long seriesId + @Parameter(description = "미디어 ID", required = true, example = "1") @PathVariable Long mediaId ); } diff --git a/apps/api-admin/src/main/java/com/ott/api_admin/series/controller/BackOfficeSeriesController.java b/apps/api-admin/src/main/java/com/ott/api_admin/series/controller/BackOfficeSeriesController.java index c2ac3a0..528985d 100644 --- a/apps/api-admin/src/main/java/com/ott/api_admin/series/controller/BackOfficeSeriesController.java +++ b/apps/api-admin/src/main/java/com/ott/api_admin/series/controller/BackOfficeSeriesController.java @@ -1,38 +1,38 @@ -//package com.ott.api_admin.series.controller; -// -//import com.ott.api_admin.series.dto.response.SeriesDetailResponse; -//import com.ott.api_admin.series.dto.response.SeriesListResponse; -//import com.ott.api_admin.series.service.BackOfficeSeriesService; -//import com.ott.common.web.response.PageResponse; -//import com.ott.common.web.response.SuccessResponse; -//import lombok.RequiredArgsConstructor; -//import org.springframework.http.ResponseEntity; -//import org.springframework.web.bind.annotation.*; -// -//@RestController -//@RequestMapping("/back-office") -//@RequiredArgsConstructor -//public class BackOfficeSeriesController implements BackOfficeSeriesApi { -// -// private final BackOfficeSeriesService backOfficeSeriesService; -// -// @Override -// @GetMapping("/admin/series") -// public ResponseEntity>> getSeries( -// @RequestParam(value = "page", defaultValue = "0") Integer page, -// @RequestParam(value = "size", defaultValue = "10") Integer size, -// @RequestParam(value = "searchWord", required = false) String searchWord -// ) { -// return ResponseEntity.ok( -// SuccessResponse.of(backOfficeSeriesService.getSeries(page, size, searchWord)) -// ); -// } -// -// @Override -// @GetMapping("/admin/series/{seriesId}") -// public ResponseEntity> getSeriesDetail(@PathVariable("seriesId") Long seriesId) { -// return ResponseEntity.ok( -// SuccessResponse.of(backOfficeSeriesService.getSeriesDetail(seriesId)) -// ); -// } -//} +package com.ott.api_admin.series.controller; + +import com.ott.api_admin.series.dto.response.SeriesDetailResponse; +import com.ott.api_admin.series.dto.response.SeriesListResponse; +import com.ott.api_admin.series.service.BackOfficeSeriesService; +import com.ott.common.web.response.PageResponse; +import com.ott.common.web.response.SuccessResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping("/back-office") +@RequiredArgsConstructor +public class BackOfficeSeriesController implements BackOfficeSeriesApi { + + private final BackOfficeSeriesService backOfficeSeriesService; + + @Override + @GetMapping("/admin/series") + public ResponseEntity>> getSeries( + @RequestParam(value = "page", defaultValue = "0") Integer page, + @RequestParam(value = "size", defaultValue = "10") Integer size, + @RequestParam(value = "searchWord", required = false) String searchWord + ) { + return ResponseEntity.ok( + SuccessResponse.of(backOfficeSeriesService.getSeries(page, size, searchWord)) + ); + } + + @Override + @GetMapping("/admin/series/{mediaId}") + public ResponseEntity> getSeriesDetail(@PathVariable("mediaId") Long mediaId) { + return ResponseEntity.ok( + SuccessResponse.of(backOfficeSeriesService.getSeriesDetail(mediaId)) + ); + } +} diff --git a/apps/api-admin/src/main/java/com/ott/api_admin/series/dto/response/SeriesListResponse.java b/apps/api-admin/src/main/java/com/ott/api_admin/series/dto/response/SeriesListResponse.java index 4b5b74a..444547a 100644 --- a/apps/api-admin/src/main/java/com/ott/api_admin/series/dto/response/SeriesListResponse.java +++ b/apps/api-admin/src/main/java/com/ott/api_admin/series/dto/response/SeriesListResponse.java @@ -8,8 +8,8 @@ @Schema(description = "시리즈 목록 조회 응답") public record SeriesListResponse( - @Schema(type = "Long", description = "시리즈 ID", example = "1") - Long seriesId, + @Schema(type = "Long", description = "미디어 ID (시리즈에서 참조)", example = "1") + Long mediaId, @Schema(type = "String", description = "썸네일 URL", example = "https://cdn.example.com/thumbnail.jpg") String thumbnailUrl, diff --git a/apps/api-admin/src/main/java/com/ott/api_admin/series/mapper/BackOfficeSeriesMapper.java b/apps/api-admin/src/main/java/com/ott/api_admin/series/mapper/BackOfficeSeriesMapper.java index d1a4b90..7580f09 100644 --- a/apps/api-admin/src/main/java/com/ott/api_admin/series/mapper/BackOfficeSeriesMapper.java +++ b/apps/api-admin/src/main/java/com/ott/api_admin/series/mapper/BackOfficeSeriesMapper.java @@ -1,59 +1,60 @@ -//package com.ott.api_admin.series.mapper; -// -//import com.ott.api_admin.series.dto.response.SeriesDetailResponse; -//import com.ott.api_admin.series.dto.response.SeriesListResponse; -//import com.ott.domain.series.domain.Series; -//import com.ott.domain.series_tag.domain.SeriesTag; -//import org.springframework.stereotype.Component; -// -//import java.util.List; -// -//@Component -//public class BackOfficeSeriesMapper { -// -// public SeriesListResponse toSeriesListResponse(Series series, List seriesTagList) { -// String categoryName = extractCategoryName(seriesTagList); -// List tagNameList = extractTagNameList(seriesTagList); -// -// return new SeriesListResponse( -// series.getId(), -// series.getThumbnailUrl(), -// series.getTitle(), -// categoryName, -// tagNameList, -// series.getPublicStatus() -// ); -// } -// -// public SeriesDetailResponse toSeriesDetailResponse(Series series, List seriesTagList) { -// String categoryName = extractCategoryName(seriesTagList); -// List tagNameList = extractTagNameList(seriesTagList); -// -// return new SeriesDetailResponse( -// series.getId(), -// series.getTitle(), -// series.getDescription(), -// categoryName, -// tagNameList, -// series.getPublicStatus(), -// series.getUploader().getNickname(), -// series.getBookmarkCount(), -// series.getActors(), -// series.getPosterUrl(), -// series.getThumbnailUrl() -// ); -// } -// -// private String extractCategoryName(List seriesTagList) { -// return seriesTagList.stream() -// .findFirst() -// .map(st -> st.getTag().getCategory().getName()) -// .orElse(null); -// } -// -// private List extractTagNameList(List seriesTagList) { -// return seriesTagList.stream() -// .map(st -> st.getTag().getName()) -// .toList(); -// } -//} +package com.ott.api_admin.series.mapper; + +import com.ott.api_admin.series.dto.response.SeriesDetailResponse; +import com.ott.api_admin.series.dto.response.SeriesListResponse; +import com.ott.domain.media.domain.Media; +import com.ott.domain.media_tag.domain.MediaTag; +import com.ott.domain.series.domain.Series; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +public class BackOfficeSeriesMapper { + + public SeriesListResponse toSeriesListResponse(Media media, List mediaTagList) { + String categoryName = extractCategoryName(mediaTagList); + List tagNameList = extractTagNameList(mediaTagList); + + return new SeriesListResponse( + media.getId(), + media.getThumbnailUrl(), + media.getTitle(), + categoryName, + tagNameList, + media.getPublicStatus() + ); + } + + public SeriesDetailResponse toSeriesDetailResponse(Series series, Media media, String uploaderName, List mediaTagList) { + String categoryName = extractCategoryName(mediaTagList); + List tagNameList = extractTagNameList(mediaTagList); + + return new SeriesDetailResponse( + series.getId(), + media.getTitle(), + media.getDescription(), + categoryName, + tagNameList, + media.getPublicStatus(), + uploaderName, + media.getBookmarkCount(), + series.getActors(), + media.getPosterUrl(), + media.getThumbnailUrl() + ); + } + + private String extractCategoryName(List mediaTagList) { + return mediaTagList.stream() + .findFirst() + .map(mt -> mt.getTag().getCategory().getName()) + .orElse(null); + } + + private List extractTagNameList(List mediaTagList) { + return mediaTagList.stream() + .map(mt -> mt.getTag().getName()) + .toList(); + } +} diff --git a/apps/api-admin/src/main/java/com/ott/api_admin/series/service/BackOfficeSeriesService.java b/apps/api-admin/src/main/java/com/ott/api_admin/series/service/BackOfficeSeriesService.java index 0615ec6..5d11f8e 100644 --- a/apps/api-admin/src/main/java/com/ott/api_admin/series/service/BackOfficeSeriesService.java +++ b/apps/api-admin/src/main/java/com/ott/api_admin/series/service/BackOfficeSeriesService.java @@ -1,80 +1,86 @@ -//package com.ott.api_admin.series.service; -// -//import com.ott.api_admin.series.dto.response.SeriesDetailResponse; -//import com.ott.api_admin.series.dto.response.SeriesListResponse; -//import com.ott.api_admin.series.mapper.BackOfficeSeriesMapper; -//import com.ott.common.web.exception.BusinessException; -//import com.ott.common.web.exception.ErrorCode; -//import com.ott.domain.series.repository.SeriesRepository; -//import com.ott.domain.series_tag.repository.SeriesTagRepository; -//import com.ott.common.web.response.PageInfo; -//import com.ott.common.web.response.PageResponse; -//import com.ott.domain.series.domain.Series; -//import com.ott.domain.series_tag.domain.SeriesTag; -//import lombok.RequiredArgsConstructor; -//import org.springframework.data.domain.Page; -//import org.springframework.data.domain.PageRequest; -//import org.springframework.data.domain.Pageable; -//import org.springframework.data.domain.Sort; -//import org.springframework.stereotype.Service; -//import org.springframework.transaction.annotation.Transactional; -//import org.springframework.util.StringUtils; -// -//import java.util.Collections; -//import java.util.List; -//import java.util.Map; -//import java.util.stream.Collectors; -// -//@RequiredArgsConstructor -//@Service -//public class BackOfficeSeriesService { -// -// private final BackOfficeSeriesMapper backOfficeSeriesMapper; -// -// private final SeriesRepository seriesRepository; -// private final SeriesTagRepository seriesTagRepository; -// -// @Transactional(readOnly = true) -// public PageResponse getSeries(int page, int size, String searchWord) { -// Pageable pageable = PageRequest.of(page, size); -// -// // 1. keyword 유무에 따라 분기 / 시리즈 대상 페이징 -// Page seriesPage = seriesRepository.findSeriesList(pageable, searchWord); -// -// // 2. 조회된 시리즈 ID 목록 추출 -// List seriesIdList = seriesPage.getContent().stream() -// .map(Series::getId) -// .toList(); -// -// // 3. IN절로 태그 일괄 조회 -// Map> tagListBySeriesId = seriesIdList.isEmpty() -// ? Collections.emptyMap() -// : seriesTagRepository.findWithTagAndCategoryBySeriesIds(seriesIdList).stream() -// .collect(Collectors.groupingBy(st -> st.getSeries().getId())); -// -// List responseList = seriesPage.getContent().stream() -// .map(series -> backOfficeSeriesMapper.toSeriesListResponse( -// series, -// tagListBySeriesId.getOrDefault(series.getId(), List.of()) -// )) -// .toList(); -// -// PageInfo pageInfo = PageInfo.toPageInfo( -// seriesPage.getNumber(), -// seriesPage.getTotalPages(), -// seriesPage.getSize() -// ); -// return PageResponse.toPageResponse(pageInfo, responseList); -// } -// -// @Transactional(readOnly = true) -// public SeriesDetailResponse getSeriesDetail(Long seriesId) { -// Series series = seriesRepository.findById(seriesId) -// .orElseThrow(() -> new BusinessException(ErrorCode.SERIES_NOT_FOUND)); -// -// List seriesTagList = seriesTagRepository -// .findWithTagAndCategoryBySeriesIds(List.of(seriesId)); -// -// return backOfficeSeriesMapper.toSeriesDetailResponse(series, seriesTagList); -// } -//} +package com.ott.api_admin.series.service; + +import com.ott.api_admin.series.dto.response.SeriesDetailResponse; +import com.ott.api_admin.series.dto.response.SeriesListResponse; +import com.ott.api_admin.series.mapper.BackOfficeSeriesMapper; +import com.ott.common.web.exception.BusinessException; +import com.ott.common.web.exception.ErrorCode; +import com.ott.domain.common.MediaType; +import com.ott.domain.media.domain.Media; +import com.ott.domain.media.repository.MediaRepository; +import com.ott.domain.media_tag.domain.MediaTag; +import com.ott.domain.media_tag.repository.MediaTagRepository; +import com.ott.common.web.response.PageInfo; +import com.ott.common.web.response.PageResponse; +import com.ott.domain.series.domain.Series; +import com.ott.domain.series.repository.SeriesRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.PageRequest; +import org.springframework.data.domain.Pageable; +import org.springframework.stereotype.Service; +import org.springframework.transaction.annotation.Transactional; + +import java.util.Collections; +import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + +@RequiredArgsConstructor +@Service +public class BackOfficeSeriesService { + + private final BackOfficeSeriesMapper backOfficeSeriesMapper; + + private final MediaRepository mediaRepository; + private final MediaTagRepository mediaTagRepository; + private final SeriesRepository seriesRepository; + + @Transactional(readOnly = true) + public PageResponse getSeries(int page, int size, String searchWord) { + Pageable pageable = PageRequest.of(page, size); + + // 1. 미디어 중 시리즈 대상 페이징 + Page mediaPage = mediaRepository.findMediaListByMediaType(pageable, MediaType.SERIES, searchWord); + + // 2. 조회된 미디어 ID 목록 추출 + List mediaIdList = mediaPage.getContent().stream() + .map(Media::getId) + .toList(); + + // 3. IN절로 태그 일괄 조회 + Map> tagListByMediaId = mediaIdList.isEmpty() + ? Collections.emptyMap() + : mediaTagRepository.findWithTagAndCategoryByMediaIds(mediaIdList).stream() + .collect(Collectors.groupingBy(mt -> mt.getMedia().getId())); + + List responseList = mediaPage.getContent().stream() + .map(media -> backOfficeSeriesMapper.toSeriesListResponse( + media, + tagListByMediaId.getOrDefault(media.getId(), List.of()) + )) + .toList(); + + PageInfo pageInfo = PageInfo.toPageInfo( + mediaPage.getNumber(), + mediaPage.getTotalPages(), + mediaPage.getSize() + ); + return PageResponse.toPageResponse(pageInfo, responseList); + } + + @Transactional(readOnly = true) + public SeriesDetailResponse getSeriesDetail(Long mediaId) { + // 1. Series + Media + Uploader 한 번에 조회 + Series series = seriesRepository.findWithMediaAndUploaderByMediaId(mediaId) + .orElseThrow(() -> new BusinessException(ErrorCode.SERIES_NOT_FOUND)); + + Media media = series.getMedia(); + String uploaderNickname = media.getUploader().getNickname(); + + // 2. 태그 조회 + List mediaTagList = mediaTagRepository.findWithTagAndCategoryByMediaId(mediaId); + + return backOfficeSeriesMapper.toSeriesDetailResponse(series, media, uploaderNickname, mediaTagList); + } +} diff --git a/modules/domain/src/main/java/com/ott/domain/media/repository/MediaRepository.java b/modules/domain/src/main/java/com/ott/domain/media/repository/MediaRepository.java new file mode 100644 index 0000000..97ffc04 --- /dev/null +++ b/modules/domain/src/main/java/com/ott/domain/media/repository/MediaRepository.java @@ -0,0 +1,7 @@ +package com.ott.domain.media.repository; + +import com.ott.domain.media.domain.Media; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MediaRepository extends JpaRepository, MediaRepositoryCustom { +} diff --git a/modules/domain/src/main/java/com/ott/domain/media/repository/MediaRepositoryCustom.java b/modules/domain/src/main/java/com/ott/domain/media/repository/MediaRepositoryCustom.java new file mode 100644 index 0000000..7a7af15 --- /dev/null +++ b/modules/domain/src/main/java/com/ott/domain/media/repository/MediaRepositoryCustom.java @@ -0,0 +1,11 @@ +package com.ott.domain.media.repository; + +import com.ott.domain.common.MediaType; +import com.ott.domain.media.domain.Media; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; + +public interface MediaRepositoryCustom { + + Page findMediaListByMediaType(Pageable pageable, MediaType mediaType, String searchWord); +} diff --git a/modules/domain/src/main/java/com/ott/domain/media/repository/MediaRepositoryImpl.java b/modules/domain/src/main/java/com/ott/domain/media/repository/MediaRepositoryImpl.java new file mode 100644 index 0000000..4c2b2f9 --- /dev/null +++ b/modules/domain/src/main/java/com/ott/domain/media/repository/MediaRepositoryImpl.java @@ -0,0 +1,52 @@ +package com.ott.domain.media.repository; + +import com.ott.domain.common.MediaType; +import com.ott.domain.media.domain.Media; +import com.querydsl.core.types.dsl.BooleanExpression; +import com.querydsl.jpa.impl.JPAQuery; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; +import org.springframework.data.domain.Page; +import org.springframework.data.domain.Pageable; +import org.springframework.data.support.PageableExecutionUtils; +import org.springframework.util.StringUtils; + +import java.util.List; + +import static com.ott.domain.media.domain.QMedia.media; + +@RequiredArgsConstructor +public class MediaRepositoryImpl implements MediaRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + @Override + public Page findMediaListByMediaType(Pageable pageable, MediaType mediaType, String searchWord) { + List mediaList = queryFactory + .selectFrom(media) + .where( + media.mediaType.eq(mediaType), + titleContains(searchWord) + ) + .orderBy(media.createdDate.desc()) + .offset(pageable.getOffset()) + .limit(pageable.getPageSize()) + .fetch(); + + JPAQuery countQuery = queryFactory + .select(media.count()) + .from(media) + .where( + media.mediaType.eq(mediaType), + titleContains(searchWord) + ); + + return PageableExecutionUtils.getPage(mediaList, pageable, countQuery::fetchOne); + } + + private BooleanExpression titleContains(String searchWord) { + if (StringUtils.hasText(searchWord)) + return media.title.contains(searchWord); + return null; + } +} diff --git a/modules/domain/src/main/java/com/ott/domain/media_tag/repository/MediaTagRepository.java b/modules/domain/src/main/java/com/ott/domain/media_tag/repository/MediaTagRepository.java new file mode 100644 index 0000000..9fd6e01 --- /dev/null +++ b/modules/domain/src/main/java/com/ott/domain/media_tag/repository/MediaTagRepository.java @@ -0,0 +1,7 @@ +package com.ott.domain.media_tag.repository; + +import com.ott.domain.media_tag.domain.MediaTag; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface MediaTagRepository extends JpaRepository, MediaTagRepositoryCustom { +} diff --git a/modules/domain/src/main/java/com/ott/domain/media_tag/repository/MediaTagRepositoryCustom.java b/modules/domain/src/main/java/com/ott/domain/media_tag/repository/MediaTagRepositoryCustom.java new file mode 100644 index 0000000..945d74b --- /dev/null +++ b/modules/domain/src/main/java/com/ott/domain/media_tag/repository/MediaTagRepositoryCustom.java @@ -0,0 +1,12 @@ +package com.ott.domain.media_tag.repository; + +import com.ott.domain.media_tag.domain.MediaTag; + +import java.util.List; + +public interface MediaTagRepositoryCustom { + + List findWithTagAndCategoryByMediaIds(List mediaIds); + + List findWithTagAndCategoryByMediaId(Long mediaId); +} diff --git a/modules/domain/src/main/java/com/ott/domain/media_tag/repository/MediaTagRepositoryImpl.java b/modules/domain/src/main/java/com/ott/domain/media_tag/repository/MediaTagRepositoryImpl.java new file mode 100644 index 0000000..d3522e3 --- /dev/null +++ b/modules/domain/src/main/java/com/ott/domain/media_tag/repository/MediaTagRepositoryImpl.java @@ -0,0 +1,37 @@ +package com.ott.domain.media_tag.repository; + +import com.ott.domain.media_tag.domain.MediaTag; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; + +import java.util.List; + +import static com.ott.domain.media_tag.domain.QMediaTag.mediaTag; +import static com.ott.domain.tag.domain.QTag.tag; +import static com.ott.domain.category.domain.QCategory.category; + +@RequiredArgsConstructor +public class MediaTagRepositoryImpl implements MediaTagRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + @Override + public List findWithTagAndCategoryByMediaIds(List mediaIds) { + return queryFactory + .selectFrom(mediaTag) + .join(mediaTag.tag, tag).fetchJoin() + .join(tag.category, category).fetchJoin() + .where(mediaTag.media.id.in(mediaIds)) + .fetch(); + } + + @Override + public List findWithTagAndCategoryByMediaId(Long mediaId) { + return queryFactory + .selectFrom(mediaTag) + .join(mediaTag.tag, tag).fetchJoin() + .join(tag.category, category).fetchJoin() + .where(mediaTag.media.id.eq(mediaId)) + .fetch(); + } +} diff --git a/modules/domain/src/main/java/com/ott/domain/series/repository/SeriesRepository.java b/modules/domain/src/main/java/com/ott/domain/series/repository/SeriesRepository.java index 1cea6a4..cb671b4 100644 --- a/modules/domain/src/main/java/com/ott/domain/series/repository/SeriesRepository.java +++ b/modules/domain/src/main/java/com/ott/domain/series/repository/SeriesRepository.java @@ -1,17 +1,17 @@ -//package com.ott.domain.series.repository; -// -//import java.util.List; -// -//import org.springframework.data.domain.Pageable; -//import org.springframework.data.jpa.repository.JpaRepository; -//import org.springframework.data.jpa.repository.Query; -//import org.springframework.data.repository.query.Param; -// -//import com.ott.domain.common.Status; -//import com.ott.domain.series.domain.Series; -// -//public interface SeriesRepository extends JpaRepository, SeriesRepositoryCustom { -// +package com.ott.domain.series.repository; + +import java.util.List; + +import org.springframework.data.domain.Pageable; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; + +import com.ott.domain.common.Status; +import com.ott.domain.series.domain.Series; + +public interface SeriesRepository extends JpaRepository, SeriesRepositoryCustom { + // // 제목에 검색어 포함, 상태 ACTIVE인 시리즈 검색 (최신순 정렬) // @Query("SELECT s FROM Series s " + // "WHERE LOWER(s.title) LIKE LOWER(CONCAT('%', :keyword, '%')) " + @@ -20,4 +20,4 @@ // List searchLatest(@Param("keyword") String keyword, // @Param("status") Status status, // Pageable pageable); -//} +} diff --git a/modules/domain/src/main/java/com/ott/domain/series/repository/SeriesRepositoryCustom.java b/modules/domain/src/main/java/com/ott/domain/series/repository/SeriesRepositoryCustom.java index f5fc2b6..aae6a81 100644 --- a/modules/domain/src/main/java/com/ott/domain/series/repository/SeriesRepositoryCustom.java +++ b/modules/domain/src/main/java/com/ott/domain/series/repository/SeriesRepositoryCustom.java @@ -1,10 +1,10 @@ package com.ott.domain.series.repository; import com.ott.domain.series.domain.Series; -import org.springframework.data.domain.Page; -import org.springframework.data.domain.Pageable; + +import java.util.Optional; public interface SeriesRepositoryCustom { - Page findSeriesList(Pageable pageable, String keyword); + Optional findWithMediaAndUploaderByMediaId(Long mediaId); } diff --git a/modules/domain/src/main/java/com/ott/domain/series/repository/SeriesRepositoryImpl.java b/modules/domain/src/main/java/com/ott/domain/series/repository/SeriesRepositoryImpl.java index 4dc78ec..daf832c 100644 --- a/modules/domain/src/main/java/com/ott/domain/series/repository/SeriesRepositoryImpl.java +++ b/modules/domain/src/main/java/com/ott/domain/series/repository/SeriesRepositoryImpl.java @@ -1,45 +1,29 @@ -//package com.ott.domain.series.repository; -// -//import com.ott.domain.series.domain.Series; -//import com.querydsl.core.types.dsl.BooleanExpression; -//import com.querydsl.jpa.impl.JPAQuery; -//import com.querydsl.jpa.impl.JPAQueryFactory; -//import lombok.RequiredArgsConstructor; -//import org.springframework.data.domain.Page; -//import org.springframework.data.domain.Pageable; -//import org.springframework.data.support.PageableExecutionUtils; -//import org.springframework.util.StringUtils; -// -//import java.util.List; -// -//import static com.ott.domain.series.domain.QSeries.series; -// -//@RequiredArgsConstructor -//public class SeriesRepositoryImpl implements SeriesRepositoryCustom { -// -// private final JPAQueryFactory queryFactory; -// -// @Override -// public Page findSeriesList(Pageable pageable, String searchWord) { -// List seriesList = queryFactory -// .selectFrom(series) -// .where(titleContains(searchWord)) -// .orderBy(series.createdDate.desc()) -// .offset(pageable.getOffset()) -// .limit(pageable.getPageSize()) -// .fetch(); -// -// JPAQuery countQuery = queryFactory -// .select(series.count()) -// .from(series) -// .where(titleContains(searchWord)); -// -// return PageableExecutionUtils.getPage(seriesList, pageable, countQuery::fetchOne); -// } -// -// private BooleanExpression titleContains(String searchWord) { -// if (StringUtils.hasText(searchWord)) -// return series.title.contains(searchWord); -// return null; -// } -//} +package com.ott.domain.series.repository; + +import com.ott.domain.series.domain.Series; +import com.querydsl.jpa.impl.JPAQueryFactory; +import lombok.RequiredArgsConstructor; + +import java.util.Optional; + +import static com.ott.domain.media.domain.QMedia.media; +import static com.ott.domain.member.domain.QMember.member; +import static com.ott.domain.series.domain.QSeries.series; + +@RequiredArgsConstructor +public class SeriesRepositoryImpl implements SeriesRepositoryCustom { + + private final JPAQueryFactory queryFactory; + + @Override + public Optional findWithMediaAndUploaderByMediaId(Long mediaId) { + Series result = queryFactory + .selectFrom(series) + .join(series.media, media).fetchJoin() + .join(media.uploader, member).fetchJoin() + .where(media.id.eq(mediaId)) + .fetchOne(); + + return Optional.ofNullable(result); + } +}