diff --git a/app/api/show-api/src/main/java/com/example/artist/service/ArtistAdminService.java b/app/api/show-api/src/main/java/com/example/artist/service/ArtistAdminService.java index 66cb1137..1858a973 100644 --- a/app/api/show-api/src/main/java/com/example/artist/service/ArtistAdminService.java +++ b/app/api/show-api/src/main/java/com/example/artist/service/ArtistAdminService.java @@ -5,6 +5,7 @@ import com.example.artist.service.dto.request.ArtistUpdateServiceRequest; import com.example.artist.service.dto.response.ArtistDetailServiceResponse; import com.example.artist.service.dto.response.ArtistKoreanNameServiceResponse; +import com.example.artist.service.dto.response.ArtistKoreanNameWithShowIdServiceResponse; import com.example.component.FileUploadComponent; import java.util.List; import java.util.NoSuchElementException; @@ -43,6 +44,12 @@ public List findAllArtistKoreanName() { .toList(); } + public List findArtistKoreanNamesWithShowId() { + return artistUseCase.findArtistKoreanNamesWithShowId().stream() + .map(ArtistKoreanNameWithShowIdServiceResponse::from) + .toList(); + } + public ArtistDetailServiceResponse findArtistById(UUID id) { ArtistDetailDomainResponse response; try { diff --git a/app/api/show-api/src/main/java/com/example/artist/service/dto/response/ArtistKoreanNameWithShowIdServiceResponse.java b/app/api/show-api/src/main/java/com/example/artist/service/dto/response/ArtistKoreanNameWithShowIdServiceResponse.java new file mode 100644 index 00000000..259edf69 --- /dev/null +++ b/app/api/show-api/src/main/java/com/example/artist/service/dto/response/ArtistKoreanNameWithShowIdServiceResponse.java @@ -0,0 +1,27 @@ +package com.example.artist.service.dto.response; + +import java.util.List; +import java.util.UUID; +import lombok.Builder; +import org.example.dto.artist.response.ArtistKoreanNamesWithShowIdDomainResponse; + +@Builder +public record ArtistKoreanNameWithShowIdServiceResponse( + UUID showId, + List koreanNameServiceResponses +) { + + public static ArtistKoreanNameWithShowIdServiceResponse from( + ArtistKoreanNamesWithShowIdDomainResponse domainResponse + ) { + var koreanNames = domainResponse.koreanNameDomainResponses() + .stream() + .map(ArtistKoreanNameServiceResponse::new) + .toList(); + + return ArtistKoreanNameWithShowIdServiceResponse.builder() + .showId(domainResponse.showId()) + .koreanNameServiceResponses(koreanNames) + .build(); + } +} diff --git a/app/api/show-api/src/main/java/com/example/genre/service/GenreAdminService.java b/app/api/show-api/src/main/java/com/example/genre/service/GenreAdminService.java index 5ed4d06a..6b186e58 100644 --- a/app/api/show-api/src/main/java/com/example/genre/service/GenreAdminService.java +++ b/app/api/show-api/src/main/java/com/example/genre/service/GenreAdminService.java @@ -4,6 +4,7 @@ import com.example.genre.service.dto.request.GenreCreateServiceRequest; import com.example.genre.service.dto.request.GenreUpdateServiceRequest; import com.example.genre.service.dto.response.GenreNameServiceResponse; +import com.example.genre.service.dto.response.GenreNameWithShowIdServiceResponse; import java.util.List; import java.util.NoSuchElementException; import java.util.UUID; @@ -23,6 +24,11 @@ public void save(GenreCreateServiceRequest genreCreateServiceRequest) { genreUseCase.save(genreCreateServiceRequest.toGenre()); } + public List findGenreNamesWithShowId() { + return genreUseCase.findGenreNamesWithShowId().stream() + .map(GenreNameWithShowIdServiceResponse::new) + .toList(); + } public List findAllGenres() { List genres = genreUseCase.findAllGenres(); diff --git a/app/api/show-api/src/main/java/com/example/genre/service/dto/response/GenreNameWithShowIdServiceResponse.java b/app/api/show-api/src/main/java/com/example/genre/service/dto/response/GenreNameWithShowIdServiceResponse.java new file mode 100644 index 00000000..c2eadb9a --- /dev/null +++ b/app/api/show-api/src/main/java/com/example/genre/service/dto/response/GenreNameWithShowIdServiceResponse.java @@ -0,0 +1,23 @@ +package com.example.genre.service.dto.response; + +import java.util.List; +import java.util.UUID; +import org.example.dto.genre.response.GenreNamesWithShowIdDomainResponse; + +public record GenreNameWithShowIdServiceResponse( + UUID showId, + List genreNames +) { + + public GenreNameWithShowIdServiceResponse( + GenreNamesWithShowIdDomainResponse response + ) { + this( + response.showId(), + response.genreNames().stream() + .map(GenreNameServiceResponse::new) + .toList() + ); + } + +} diff --git a/app/api/show-api/src/main/java/com/example/show/controller/ShowAdminController.java b/app/api/show-api/src/main/java/com/example/show/controller/ShowAdminController.java index 76b57c61..9a097c3d 100644 --- a/app/api/show-api/src/main/java/com/example/show/controller/ShowAdminController.java +++ b/app/api/show-api/src/main/java/com/example/show/controller/ShowAdminController.java @@ -56,8 +56,9 @@ public String createShow(@Valid ShowCreateApiForm showCreateApiForm) { @GetMapping("/list") public String findAllShow(Model model) { - List shows = showAdminService.findAllShowInfos() - .stream() + var showWithTicketingTimes = showAdminService.findShowDetailWithTicketingTimes(); + + List shows = showWithTicketingTimes.stream() .map(ShowInfoApiResponse::new) .toList(); diff --git a/app/api/show-api/src/main/java/com/example/show/controller/dto/response/ShowInfoApiResponse.java b/app/api/show-api/src/main/java/com/example/show/controller/dto/response/ShowInfoApiResponse.java index db6027ae..d0405e5d 100644 --- a/app/api/show-api/src/main/java/com/example/show/controller/dto/response/ShowInfoApiResponse.java +++ b/app/api/show-api/src/main/java/com/example/show/controller/dto/response/ShowInfoApiResponse.java @@ -46,4 +46,11 @@ public ShowInfoApiResponse(ShowInfoServiceResponse showInfoServiceResponse) { ); } + public static List from( + List showInfoServiceResponses + ) { + return showInfoServiceResponses.stream() + .map(ShowInfoApiResponse::new) + .toList(); + } } diff --git a/app/api/show-api/src/main/java/com/example/show/controller/dto/response/ShowWithTicketingTimesServiceResponse.java b/app/api/show-api/src/main/java/com/example/show/controller/dto/response/ShowWithTicketingTimesServiceResponse.java new file mode 100644 index 00000000..68b7d8e4 --- /dev/null +++ b/app/api/show-api/src/main/java/com/example/show/controller/dto/response/ShowWithTicketingTimesServiceResponse.java @@ -0,0 +1,50 @@ +package com.example.show.controller.dto.response; + +import com.example.show.service.dto.response.ShowSeatServiceResponse; +import com.example.show.service.dto.response.ShowTicketingSiteServiceResponse; +import com.example.show.service.dto.response.ShowTicketingTimeServiceResponse; +import java.time.LocalDate; +import java.util.List; +import java.util.UUID; +import org.example.dto.show.response.ShowTicketingTimeDomainResponse; +import org.example.dto.show.response.ShowWithTicketingTimesDomainResponse; + +public record ShowWithTicketingTimesServiceResponse( + UUID id, + String title, + String content, + LocalDate startDate, + LocalDate endDate, + String location, + String image, + ShowSeatServiceResponse seats, + ShowTicketingSiteServiceResponse ticketingSiteInfos, + List ticketingTimes +) { + + public ShowWithTicketingTimesServiceResponse( + ShowWithTicketingTimesDomainResponse domainResponse + ) { + this( + domainResponse.show().id(), + domainResponse.show().title(), + domainResponse.show().content(), + domainResponse.show().startDate(), + domainResponse.show().endDate(), + domainResponse.show().location(), + domainResponse.show().image(), + ShowSeatServiceResponse.from(domainResponse.show().seatPrices()), + ShowTicketingSiteServiceResponse.from(domainResponse.show().ticketingSites()), + toShowTicketingTimeServiceResponses(domainResponse.ticketingTimes()) + ); + } + + private static List toShowTicketingTimeServiceResponses( + List ticketingSites + ) { + return ticketingSites.stream() + .map(ShowTicketingTimeServiceResponse::from) + .toList(); + } + +} diff --git a/app/api/show-api/src/main/java/com/example/show/service/ShowAdminService.java b/app/api/show-api/src/main/java/com/example/show/service/ShowAdminService.java index c3e0e02c..d8afcafb 100644 --- a/app/api/show-api/src/main/java/com/example/show/service/ShowAdminService.java +++ b/app/api/show-api/src/main/java/com/example/show/service/ShowAdminService.java @@ -14,6 +14,8 @@ import lombok.RequiredArgsConstructor; import org.example.dto.show.response.ShowInfoDomainResponse; import org.example.exception.BusinessException; +import org.example.usecase.artist.ArtistUseCase; +import org.example.usecase.genre.GenreUseCase; import org.example.usecase.show.ShowUseCase; import org.springframework.stereotype.Service; @@ -22,6 +24,8 @@ public class ShowAdminService { private final ShowUseCase showUseCase; + private final GenreUseCase genreUseCase; + private final ArtistUseCase artistUseCase; private final FileUploadComponent fileUploadComponent; private final MessagePublisher messagePublisher; @@ -41,11 +45,17 @@ public void save(ShowCreateServiceRequest showCreateServiceRequest) { ); } - public List findAllShowInfos() { - List showInfoDomainResponse = showUseCase.findAllShowInfos(); - return showInfoDomainResponse.stream() - .map(ShowInfoServiceResponse::new) - .toList(); + public List findShowDetailWithTicketingTimes() { + var showWithTicketingTimesDomainResponses = showUseCase.findShowDetailWithTicketingTimes(); + var artistKoreanNameWithShowIdDomainResponses = artistUseCase.findArtistKoreanNamesWithShowId(); + var genreNameWithShowIdDomainResponses = genreUseCase.findGenreNamesWithShowId(); + + return ShowInfoServiceResponse.as( + showWithTicketingTimesDomainResponses, + artistKoreanNameWithShowIdDomainResponses, + genreNameWithShowIdDomainResponses + ); + } public ShowInfoServiceResponse findShowInfo(UUID id) { diff --git a/app/api/show-api/src/main/java/com/example/show/service/dto/response/ShowInfoServiceResponse.java b/app/api/show-api/src/main/java/com/example/show/service/dto/response/ShowInfoServiceResponse.java index 7e9516f7..b609cbbe 100644 --- a/app/api/show-api/src/main/java/com/example/show/service/dto/response/ShowInfoServiceResponse.java +++ b/app/api/show-api/src/main/java/com/example/show/service/dto/response/ShowInfoServiceResponse.java @@ -8,9 +8,12 @@ import java.util.UUID; import lombok.Builder; import org.example.dto.artist.response.ArtistKoreanNameDomainResponse; +import org.example.dto.artist.response.ArtistKoreanNamesWithShowIdDomainResponse; import org.example.dto.genre.response.GenreNameDomainResponse; +import org.example.dto.genre.response.GenreNamesWithShowIdDomainResponse; import org.example.dto.show.response.ShowInfoDomainResponse; import org.example.dto.show.response.ShowTicketingTimeDomainResponse; +import org.example.dto.show.response.ShowWithTicketingTimesDomainResponse; @Builder public record ShowInfoServiceResponse( @@ -45,6 +48,43 @@ public ShowInfoServiceResponse(ShowInfoDomainResponse showInfo) { ); } + public static List as( + List showWithTicketingTimes, + List artistNamesWithShowId, + List genreNamesWithShowId + ) { + return showWithTicketingTimes.stream() + .map(showWithTicketingTime -> { + var artistKoreanNameResponses = getArtistKoreanNameResponses( + artistNamesWithShowId, + showWithTicketingTime + ); + var genreNameResponses = getGenreNameResponses( + genreNamesWithShowId, + showWithTicketingTime + ); + + return new ShowInfoServiceResponse( + showWithTicketingTime.show().id(), + showWithTicketingTime.show().title(), + showWithTicketingTime.show().content(), + showWithTicketingTime.show().startDate(), + showWithTicketingTime.show().endDate(), + showWithTicketingTime.show().location(), + showWithTicketingTime.show().image(), + ShowSeatServiceResponse.from(showWithTicketingTime.show().seatPrices()), + ShowTicketingSiteServiceResponse.from( + showWithTicketingTime.show().ticketingSites()), + showWithTicketingTime.ticketingTimes().stream() + .map(ShowTicketingTimeServiceResponse::from) + .toList(), + artistKoreanNameResponses, + genreNameResponses + ); + }) + .toList(); + } + private static List toShowTicketingTimeServiceResponses( Set ticketingSites ) { @@ -68,4 +108,28 @@ private static List toGenreNameServiceResponses( .map(GenreNameServiceResponse::new) .toList(); } + + private static List getArtistKoreanNameResponses( + List artistNamesWithShowId, + ShowWithTicketingTimesDomainResponse showWitTicketingTimes + ) { + return artistNamesWithShowId.stream() + .filter( + artistResponse -> artistResponse.showId().equals(showWitTicketingTimes.show().id())) + .flatMap(artistResponse -> artistResponse.koreanNameDomainResponses().stream()) + .map(ArtistKoreanNameServiceResponse::new) + .toList(); + } + + private static List getGenreNameResponses( + List genreNamesWithShowId, + ShowWithTicketingTimesDomainResponse showWithTicketingTimes + ) { + return genreNamesWithShowId.stream() + .filter( + genreResponse -> genreResponse.showId().equals(showWithTicketingTimes.show().id())) + .flatMap(genreResponse -> genreResponse.genreNames().stream()) + .map(GenreNameServiceResponse::new) + .toList(); + } } diff --git a/app/api/show-api/src/test/java/show/service/ShowAdminServiceTest.java b/app/api/show-api/src/test/java/show/service/ShowAdminServiceTest.java index 16f10386..9e3c7cf9 100644 --- a/app/api/show-api/src/test/java/show/service/ShowAdminServiceTest.java +++ b/app/api/show-api/src/test/java/show/service/ShowAdminServiceTest.java @@ -20,6 +20,8 @@ import org.example.dto.show.request.ShowUpdateDomainRequest; import org.example.fixture.domain.ShowArtistFixture; import org.example.fixture.domain.ShowGenreFixture; +import org.example.usecase.artist.ArtistUseCase; +import org.example.usecase.genre.GenreUseCase; import org.example.usecase.show.ShowUseCase; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; @@ -28,11 +30,15 @@ class ShowAdminServiceTest { private final ShowUseCase showUseCase = mock(ShowUseCase.class); + private final GenreUseCase genreUseCase = mock(GenreUseCase.class); + private final ArtistUseCase artistUseCase = mock(ArtistUseCase.class); private final FileUploadComponent fileUploadComponent = mock(FileUploadComponent.class); private final MessagePublisher messagePublisher = mock(MessagePublisher.class); private final ShowAdminService showAdminService = new ShowAdminService( showUseCase, + genreUseCase, + artistUseCase, fileUploadComponent, messagePublisher ); diff --git a/app/domain/show-domain/src/main/java/org/example/dto/artist/response/ArtistKoreanNamesWithShowIdDomainResponse.java b/app/domain/show-domain/src/main/java/org/example/dto/artist/response/ArtistKoreanNamesWithShowIdDomainResponse.java new file mode 100644 index 00000000..19da1e0d --- /dev/null +++ b/app/domain/show-domain/src/main/java/org/example/dto/artist/response/ArtistKoreanNamesWithShowIdDomainResponse.java @@ -0,0 +1,11 @@ +package org.example.dto.artist.response; + +import java.util.List; +import java.util.UUID; + +public record ArtistKoreanNamesWithShowIdDomainResponse( + UUID showId, + List koreanNameDomainResponses +) { + +} diff --git a/app/domain/show-domain/src/main/java/org/example/dto/genre/response/GenreNamesWithShowIdDomainResponse.java b/app/domain/show-domain/src/main/java/org/example/dto/genre/response/GenreNamesWithShowIdDomainResponse.java new file mode 100644 index 00000000..265c47ee --- /dev/null +++ b/app/domain/show-domain/src/main/java/org/example/dto/genre/response/GenreNamesWithShowIdDomainResponse.java @@ -0,0 +1,11 @@ +package org.example.dto.genre.response; + +import java.util.List; +import java.util.UUID; + +public record GenreNamesWithShowIdDomainResponse( + UUID showId, + List genreNames +) { + +} diff --git a/app/domain/show-domain/src/main/java/org/example/dto/show/response/ShowWithTicketingTimesDomainResponse.java b/app/domain/show-domain/src/main/java/org/example/dto/show/response/ShowWithTicketingTimesDomainResponse.java new file mode 100644 index 00000000..40846394 --- /dev/null +++ b/app/domain/show-domain/src/main/java/org/example/dto/show/response/ShowWithTicketingTimesDomainResponse.java @@ -0,0 +1,10 @@ +package org.example.dto.show.response; + +import java.util.List; + +public record ShowWithTicketingTimesDomainResponse( + ShowDomainResponse show, + List ticketingTimes +) { + +} diff --git a/app/domain/show-domain/src/main/java/org/example/repository/show/ShowQuerydslRepository.java b/app/domain/show-domain/src/main/java/org/example/repository/show/ShowQuerydslRepository.java index 8813f04d..cc951037 100644 --- a/app/domain/show-domain/src/main/java/org/example/repository/show/ShowQuerydslRepository.java +++ b/app/domain/show-domain/src/main/java/org/example/repository/show/ShowQuerydslRepository.java @@ -5,12 +5,13 @@ import java.util.UUID; import org.example.dto.show.response.ShowDetailDomainResponse; import org.example.dto.show.response.ShowInfoDomainResponse; +import org.example.dto.show.response.ShowWithTicketingTimesDomainResponse; public interface ShowQuerydslRepository { Optional findShowDetailById(UUID id); - List findAllShowInfos(); + List findShowDetailWithTicketingTimes(); Optional findShowInfoById(UUID id); } diff --git a/app/domain/show-domain/src/main/java/org/example/repository/show/ShowQuerydslRepositoryImpl.java b/app/domain/show-domain/src/main/java/org/example/repository/show/ShowQuerydslRepositoryImpl.java index 81dc1fc8..f025df6c 100644 --- a/app/domain/show-domain/src/main/java/org/example/repository/show/ShowQuerydslRepositoryImpl.java +++ b/app/domain/show-domain/src/main/java/org/example/repository/show/ShowQuerydslRepositoryImpl.java @@ -1,6 +1,7 @@ package org.example.repository.show; import static com.querydsl.core.group.GroupBy.groupBy; +import static com.querydsl.core.group.GroupBy.list; import static com.querydsl.core.group.GroupBy.set; import static org.example.entity.artist.QArtist.artist; import static org.example.entity.genre.QGenre.genre; @@ -25,6 +26,7 @@ import org.example.dto.show.response.ShowDomainResponse; import org.example.dto.show.response.ShowInfoDomainResponse; import org.example.dto.show.response.ShowTicketingTimeDomainResponse; +import org.example.dto.show.response.ShowWithTicketingTimesDomainResponse; import org.example.entity.show.Show; import org.springframework.stereotype.Repository; @@ -89,12 +91,14 @@ public Optional findShowDetailById(UUID id) { } @Override - public List findAllShowInfos() { - return createShowJoinArtistAndGenreQuery() + public List findShowDetailWithTicketingTimes() { + return jpaQueryFactory.selectFrom(show) + .join(showTicketingTime).on(isShowTicketingEqualShowAndIsDeletedFalse()) + .where(show.isDeleted.isFalse()) .transform( groupBy(show.id).list( Projections.constructor( - ShowInfoDomainResponse.class, + ShowWithTicketingTimesDomainResponse.class, Projections.constructor( ShowDomainResponse.class, show.id, @@ -107,21 +111,7 @@ public List findAllShowInfos() { show.seatPrices, show.ticketingSites ), - set( - Projections.constructor( - ArtistKoreanNameDomainResponse.class, - artist.id, - artist.koreanName - ) - ), - set( - Projections.constructor( - GenreNameDomainResponse.class, - genre.id, - genre.name - ) - ), - set( + list( Projections.constructor( ShowTicketingTimeDomainResponse.class, showTicketingTime.ticketingType, diff --git a/app/domain/show-domain/src/main/java/org/example/repository/show/showartist/ShowArtistQuerydslRepository.java b/app/domain/show-domain/src/main/java/org/example/repository/show/showartist/ShowArtistQuerydslRepository.java new file mode 100644 index 00000000..fc079b61 --- /dev/null +++ b/app/domain/show-domain/src/main/java/org/example/repository/show/showartist/ShowArtistQuerydslRepository.java @@ -0,0 +1,9 @@ +package org.example.repository.show.showartist; + +import java.util.List; +import org.example.dto.artist.response.ArtistKoreanNamesWithShowIdDomainResponse; + +public interface ShowArtistQuerydslRepository { + + List findArtistKoreanNamesWithShowId(); +} diff --git a/app/domain/show-domain/src/main/java/org/example/repository/show/showartist/ShowArtistQuerydslRepositoryImpl.java b/app/domain/show-domain/src/main/java/org/example/repository/show/showartist/ShowArtistQuerydslRepositoryImpl.java new file mode 100644 index 00000000..b6312e15 --- /dev/null +++ b/app/domain/show-domain/src/main/java/org/example/repository/show/showartist/ShowArtistQuerydslRepositoryImpl.java @@ -0,0 +1,45 @@ +package org.example.repository.show.showartist; + +import static com.querydsl.core.group.GroupBy.groupBy; +import static com.querydsl.core.group.GroupBy.list; +import static org.example.entity.artist.QArtist.artist; +import static org.example.entity.show.QShow.show; +import static org.example.entity.show.QShowArtist.showArtist; + +import com.querydsl.core.types.Projections; +import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.example.dto.artist.response.ArtistKoreanNameDomainResponse; +import org.example.dto.artist.response.ArtistKoreanNamesWithShowIdDomainResponse; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class ShowArtistQuerydslRepositoryImpl implements ShowArtistQuerydslRepository { + + private final JPAQueryFactory jpaQueryFactory; + + @Override + public List findArtistKoreanNamesWithShowId() { + return jpaQueryFactory.selectFrom(showArtist) + .join(show).on(show.id.eq(showArtist.showId), show.isDeleted.isFalse()) + .join(artist).on(artist.id.eq(showArtist.artistId), artist.isDeleted.isFalse()) + .where(showArtist.isDeleted.isFalse()) + .transform( + groupBy(showArtist.id).list( + Projections.constructor( + ArtistKoreanNamesWithShowIdDomainResponse.class, + show.id, + list( + Projections.constructor( + ArtistKoreanNameDomainResponse.class, + artist.id, + artist.koreanName + ) + ) + ) + ) + ); + } +} diff --git a/app/domain/show-domain/src/main/java/org/example/repository/show/showartist/ShowArtistRepository.java b/app/domain/show-domain/src/main/java/org/example/repository/show/showartist/ShowArtistRepository.java index 81d50ebd..9ec624f3 100644 --- a/app/domain/show-domain/src/main/java/org/example/repository/show/showartist/ShowArtistRepository.java +++ b/app/domain/show-domain/src/main/java/org/example/repository/show/showartist/ShowArtistRepository.java @@ -5,7 +5,8 @@ import org.example.entity.show.ShowArtist; import org.springframework.data.jpa.repository.JpaRepository; -public interface ShowArtistRepository extends JpaRepository { +public interface ShowArtistRepository extends JpaRepository, + ShowArtistQuerydslRepository { List findAllByShowIdAndIsDeletedFalse(UUID showId); diff --git a/app/domain/show-domain/src/main/java/org/example/repository/show/showgenre/ShowGenreQuerydslRepository.java b/app/domain/show-domain/src/main/java/org/example/repository/show/showgenre/ShowGenreQuerydslRepository.java new file mode 100644 index 00000000..20682ca4 --- /dev/null +++ b/app/domain/show-domain/src/main/java/org/example/repository/show/showgenre/ShowGenreQuerydslRepository.java @@ -0,0 +1,10 @@ +package org.example.repository.show.showgenre; + +import java.util.List; +import org.example.dto.genre.response.GenreNamesWithShowIdDomainResponse; + +public interface ShowGenreQuerydslRepository { + + List findGenreNamesWithShowId(); + +} diff --git a/app/domain/show-domain/src/main/java/org/example/repository/show/showgenre/ShowGenreQuerydslRepositoryImpl.java b/app/domain/show-domain/src/main/java/org/example/repository/show/showgenre/ShowGenreQuerydslRepositoryImpl.java new file mode 100644 index 00000000..a2ed3db4 --- /dev/null +++ b/app/domain/show-domain/src/main/java/org/example/repository/show/showgenre/ShowGenreQuerydslRepositoryImpl.java @@ -0,0 +1,45 @@ +package org.example.repository.show.showgenre; + +import static com.querydsl.core.group.GroupBy.groupBy; +import static com.querydsl.core.group.GroupBy.list; +import static org.example.entity.genre.QGenre.genre; +import static org.example.entity.show.QShow.show; +import static org.example.entity.show.QShowGenre.showGenre; + +import com.querydsl.core.types.Projections; +import com.querydsl.jpa.impl.JPAQueryFactory; +import java.util.List; +import lombok.RequiredArgsConstructor; +import org.example.dto.genre.response.GenreNameDomainResponse; +import org.example.dto.genre.response.GenreNamesWithShowIdDomainResponse; +import org.springframework.stereotype.Repository; + +@Repository +@RequiredArgsConstructor +public class ShowGenreQuerydslRepositoryImpl implements ShowGenreQuerydslRepository { + + private final JPAQueryFactory jpaQueryFactory; + + @Override + public List findGenreNamesWithShowId() { + return jpaQueryFactory.selectFrom(showGenre) + .join(show).on(show.id.eq(showGenre.showId), show.isDeleted.isFalse()) + .join(genre).on(genre.id.eq(showGenre.genreId), genre.isDeleted.isFalse()) + .where(showGenre.isDeleted.isFalse()) + .transform( + groupBy(showGenre.id).list( + Projections.constructor( + GenreNamesWithShowIdDomainResponse.class, + show.id, + list( + Projections.constructor( + GenreNameDomainResponse.class, + genre.id, + genre.name + ) + ) + ) + ) + ); + } +} diff --git a/app/domain/show-domain/src/main/java/org/example/repository/show/showgenre/ShowGenreRepository.java b/app/domain/show-domain/src/main/java/org/example/repository/show/showgenre/ShowGenreRepository.java index 31c1ae47..23176cf6 100644 --- a/app/domain/show-domain/src/main/java/org/example/repository/show/showgenre/ShowGenreRepository.java +++ b/app/domain/show-domain/src/main/java/org/example/repository/show/showgenre/ShowGenreRepository.java @@ -5,7 +5,8 @@ import org.example.entity.show.ShowGenre; import org.springframework.data.jpa.repository.JpaRepository; -public interface ShowGenreRepository extends JpaRepository { +public interface ShowGenreRepository extends JpaRepository, + ShowGenreQuerydslRepository { List findAllByShowIdAndIsDeletedFalse(UUID showId); diff --git a/app/domain/show-domain/src/main/java/org/example/usecase/artist/ArtistUseCase.java b/app/domain/show-domain/src/main/java/org/example/usecase/artist/ArtistUseCase.java index c0491012..cd106681 100644 --- a/app/domain/show-domain/src/main/java/org/example/usecase/artist/ArtistUseCase.java +++ b/app/domain/show-domain/src/main/java/org/example/usecase/artist/ArtistUseCase.java @@ -10,6 +10,7 @@ import org.example.dto.artist.response.ArtistDetailDomainResponse; import org.example.dto.artist.response.ArtistFilterTotalCountDomainResponse; import org.example.dto.artist.response.ArtistKoreanNameDomainResponse; +import org.example.dto.artist.response.ArtistKoreanNamesWithShowIdDomainResponse; import org.example.dto.artist.response.ArtistPaginationDomainResponse; import org.example.entity.BaseEntity; import org.example.entity.artist.Artist; @@ -56,6 +57,10 @@ public ArtistDetailDomainResponse findArtistDetailById(UUID id) { .orElseThrow(NoSuchElementException::new); } + public List findArtistKoreanNamesWithShowId() { + return showArtistRepository.findArtistKoreanNamesWithShowId(); + } + public List findAllArtistInIds(List ids) { return artistRepository.findAllInIds(ids); } @@ -146,5 +151,7 @@ private Artist findArtistById(UUID id) { return artistRepository.findById(id) .orElseThrow(NoSuchElementException::new); } + + } diff --git a/app/domain/show-domain/src/main/java/org/example/usecase/genre/GenreUseCase.java b/app/domain/show-domain/src/main/java/org/example/usecase/genre/GenreUseCase.java index 1b27e9c8..d8a20feb 100644 --- a/app/domain/show-domain/src/main/java/org/example/usecase/genre/GenreUseCase.java +++ b/app/domain/show-domain/src/main/java/org/example/usecase/genre/GenreUseCase.java @@ -5,6 +5,7 @@ import java.util.UUID; import lombok.RequiredArgsConstructor; import org.example.dto.genre.request.GenrePaginationDomainRequest; +import org.example.dto.genre.response.GenreNamesWithShowIdDomainResponse; import org.example.dto.genre.response.GenrePaginationDomainResponse; import org.example.entity.BaseEntity; import org.example.entity.artist.ArtistGenre; @@ -57,6 +58,10 @@ public Genre findGenreById(UUID id) { return genreRepository.findById(id).orElseThrow(NoSuchElementException::new); } + public List findGenreNamesWithShowId() { + return showGenreRepository.findGenreNamesWithShowId(); + } + public List findAllGenresInIds(List genreIds) { return genreRepository.findAllInId(genreIds); } diff --git a/app/domain/show-domain/src/main/java/org/example/usecase/show/ShowUseCase.java b/app/domain/show-domain/src/main/java/org/example/usecase/show/ShowUseCase.java index 25dc4421..8e7162e0 100644 --- a/app/domain/show-domain/src/main/java/org/example/usecase/show/ShowUseCase.java +++ b/app/domain/show-domain/src/main/java/org/example/usecase/show/ShowUseCase.java @@ -10,6 +10,7 @@ import org.example.dto.show.response.ShowDetailDomainResponse; import org.example.dto.show.response.ShowInfoDomainResponse; import org.example.dto.show.response.ShowSearchPaginationDomainResponse; +import org.example.dto.show.response.ShowWithTicketingTimesDomainResponse; import org.example.entity.BaseEntity; import org.example.entity.show.Show; import org.example.entity.show.ShowArtist; @@ -53,8 +54,8 @@ public void save( showTicketingTimeRepository.saveAll(showTicketingTimes); } - public List findAllShowInfos() { - return showRepository.findAllShowInfos(); + public List findShowDetailWithTicketingTimes() { + return showRepository.findShowDetailWithTicketingTimes(); } public ShowDetailDomainResponse findShowDetail(UUID id) { diff --git a/app/domain/show-domain/src/test/java/org/example/repository/show/ShowArtistRepositoryTest.java b/app/domain/show-domain/src/test/java/org/example/repository/show/ShowArtistRepositoryTest.java new file mode 100644 index 00000000..3cb7899b --- /dev/null +++ b/app/domain/show-domain/src/test/java/org/example/repository/show/ShowArtistRepositoryTest.java @@ -0,0 +1,55 @@ +package org.example.repository.show; + +import org.assertj.core.api.SoftAssertions; +import org.example.QueryTest; +import org.example.entity.artist.Artist; +import org.example.entity.show.Show; +import org.example.fixture.domain.ArtistFixture; +import org.example.fixture.domain.ShowArtistFixture; +import org.example.fixture.domain.ShowFixture; +import org.example.repository.artist.ArtistRepository; +import org.example.repository.show.showartist.ShowArtistRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +public class ShowArtistRepositoryTest extends QueryTest { + + @Autowired + private ShowArtistRepository showArtistRepository; + + @Autowired + private ShowRepository showRepository; + + @Autowired + private ArtistRepository artistRepository; + + @Test + @DisplayName("공연과 연관된 아티스트 이름을 함께 가져온다.") + void findArtistKoreanNamesWithShowId() { + //given + var artists = ArtistFixture.manSoloArtists(2); + artistRepository.saveAll(artists); + + var shows = ShowFixture.shows(2); + showRepository.saveAll(shows); + + var showArtist = ShowArtistFixture.showArtists( + shows.stream().map(Show::getId).toList(), + artists.stream().map(Artist::getId).toList(), + 2 + ); + showArtistRepository.saveAll(showArtist); + + //when + var result = showArtistRepository.findArtistKoreanNamesWithShowId(); + + //then + SoftAssertions.assertSoftly( + soft -> { + soft.assertThat(result.size()).isEqualTo(2); + soft.assertThat(result.get(0).koreanNameDomainResponses().size()).isEqualTo(1); + } + ); + } +} diff --git a/app/domain/show-domain/src/test/java/org/example/repository/show/ShowGenreRepositoryTest.java b/app/domain/show-domain/src/test/java/org/example/repository/show/ShowGenreRepositoryTest.java new file mode 100644 index 00000000..4918186f --- /dev/null +++ b/app/domain/show-domain/src/test/java/org/example/repository/show/ShowGenreRepositoryTest.java @@ -0,0 +1,55 @@ +package org.example.repository.show; + +import org.assertj.core.api.SoftAssertions; +import org.example.QueryTest; +import org.example.entity.genre.Genre; +import org.example.entity.show.Show; +import org.example.fixture.domain.GenreFixture; +import org.example.fixture.domain.ShowFixture; +import org.example.fixture.domain.ShowGenreFixture; +import org.example.repository.genre.GenreRepository; +import org.example.repository.show.showgenre.ShowGenreRepository; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +public class ShowGenreRepositoryTest extends QueryTest { + + @Autowired + private ShowGenreRepository showGenreRepository; + + @Autowired + private ShowRepository showRepository; + + @Autowired + private GenreRepository genreRepository; + + @Test + @DisplayName("공연과 연관된 장르 이름을 함께 가져온다.") + void findGenreNamesWithShowId() { + //given + var genres = GenreFixture.genres(2); + genreRepository.saveAll(genres); + + var shows = ShowFixture.shows(2); + showRepository.saveAll(shows); + + var showGenres = ShowGenreFixture.showGenres( + shows.stream().map(Show::getId).toList(), + genres.stream().map(Genre::getId).toList(), + 2 + ); + showGenreRepository.saveAll(showGenres); + + //when + var result = showGenreRepository.findGenreNamesWithShowId(); + + //then + SoftAssertions.assertSoftly( + soft -> { + soft.assertThat(result.size()).isEqualTo(2); + soft.assertThat(result.get(0).genreNames().size()).isEqualTo(1); + } + ); + } +} diff --git a/app/domain/show-domain/src/test/java/org/example/repository/show/ShowRepositoryTest.java b/app/domain/show-domain/src/test/java/org/example/repository/show/ShowRepositoryTest.java new file mode 100644 index 00000000..8cfd0717 --- /dev/null +++ b/app/domain/show-domain/src/test/java/org/example/repository/show/ShowRepositoryTest.java @@ -0,0 +1,46 @@ +package org.example.repository.show; + +import org.assertj.core.api.SoftAssertions; +import org.example.QueryTest; +import org.example.entity.show.Show; +import org.example.entity.show.ShowTicketingTime; +import org.example.fixture.domain.ShowFixture; +import org.example.fixture.domain.ShowTicketingTimeFixture; +import org.junit.jupiter.api.DisplayName; +import org.junit.jupiter.api.Test; +import org.springframework.beans.factory.annotation.Autowired; + +public class ShowRepositoryTest extends QueryTest { + + @Autowired + private ShowRepository showRepository; + + @Autowired + private ShowTicketingTimeRepository showTicketingTimeRepository; + + @Test + @DisplayName("공연 정보들은 연관된 티켓팅 시간과 함께 가져온다.") + void findShowDetailWithTicketingTimes() { + //given + Show show = ShowFixture.deafultShow(); + showRepository.save(show); + + ShowTicketingTime showNormalTicketingTime = ShowTicketingTimeFixture.showNormalTicketingTime(show); + ShowTicketingTime showPreTicketingTime = ShowTicketingTimeFixture.showPreTicketingTime(show); + showTicketingTimeRepository.save(showNormalTicketingTime); + showTicketingTimeRepository.save(showPreTicketingTime); + + + //when + var result = showRepository.findShowDetailWithTicketingTimes(); + + //then + SoftAssertions.assertSoftly( + soft -> { + soft.assertThat(result.size()).isEqualTo(1); + soft.assertThat(result.get(0).ticketingTimes().size()).isEqualTo(2); + } + ); + } + +} diff --git a/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowArtistFixture.java b/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowArtistFixture.java index 8d29b348..8448eee1 100644 --- a/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowArtistFixture.java +++ b/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowArtistFixture.java @@ -6,6 +6,17 @@ import org.example.entity.show.ShowArtist; public class ShowArtistFixture { + + public static List showArtists(List showIds, List artistIds, int count) { + return IntStream.range(0, count) + .mapToObj(i -> ShowArtist.builder() + .showId(showIds.get(i)) + .artistId(artistIds.get(i)) + .build() + ) + .toList(); + } + public static List showArtists(int count) { return IntStream.range(0, count) .mapToObj(i -> ShowArtist.builder() diff --git a/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowFixture.java b/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowFixture.java index d6c1961c..82f85662 100644 --- a/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowFixture.java +++ b/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowFixture.java @@ -1,13 +1,21 @@ package org.example.fixture.domain; import java.time.LocalDate; +import java.util.List; import java.util.Map; +import java.util.stream.IntStream; import org.example.entity.show.Show; import org.example.entity.show.info.SeatPrices; import org.example.entity.show.info.TicketingSites; public class ShowFixture { + public static List shows(int count) { + return IntStream.range(0, count) + .mapToObj(i -> deafultShow()) + .toList(); + } + public static Show deafultShow() { return Show.builder() .title("test_title") diff --git a/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowGenreFixture.java b/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowGenreFixture.java index a214049b..17c0a994 100644 --- a/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowGenreFixture.java +++ b/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowGenreFixture.java @@ -7,6 +7,15 @@ public class ShowGenreFixture { + public static List showGenres(List showIds, List genreIds, int count) { + return IntStream.range(0, count) + .mapToObj(i -> ShowGenre.builder() + .showId(showIds.get(i)) + .genreId(genreIds.get(i)) + .build()) + .toList(); + } + public static List showGenres(int count) { return IntStream.range(0, count) .mapToObj(i -> ShowGenre.builder() diff --git a/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowTicketingTimeFixture.java b/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowTicketingTimeFixture.java new file mode 100644 index 00000000..aa536601 --- /dev/null +++ b/app/domain/show-domain/src/testFixtures/java/org/example/fixture/domain/ShowTicketingTimeFixture.java @@ -0,0 +1,26 @@ +package org.example.fixture.domain; + +import java.time.LocalDateTime; +import org.example.entity.show.Show; +import org.example.entity.show.ShowTicketingTime; +import org.example.vo.TicketingType; + +public class ShowTicketingTimeFixture { + + public static ShowTicketingTime showNormalTicketingTime(Show show) { + return ShowTicketingTime.builder() + .ticketingType(TicketingType.NORMAL) + .ticketingAt(LocalDateTime.now()) + .show(show) + .build(); + } + + public static ShowTicketingTime showPreTicketingTime(Show show) { + return ShowTicketingTime.builder() + .ticketingType(TicketingType.PRE) + .ticketingAt(LocalDateTime.now()) + .show(show) + .build(); + } + +}