11package org .dfbf .soundlink .domain .emotionRecord .repository .dsl ;
22
33import com .querydsl .core .types .Projections ;
4+ import com .querydsl .core .types .dsl .BooleanExpression ;
45import com .querydsl .jpa .impl .JPAQueryFactory ;
56import lombok .RequiredArgsConstructor ;
67import org .dfbf .soundlink .domain .emotionRecord .entity .EmotionRecord ;
910import org .dfbf .soundlink .domain .user .dto .response .EmotionRecordDto ;
1011import org .dfbf .soundlink .domain .user .entity .QUser ;
1112import org .dfbf .soundlink .domain .user .entity .User ;
13+ import org .dfbf .soundlink .global .comm .enums .Emotions ;
1214import org .springframework .data .domain .Page ;
13- import org .springframework .data .domain .PageImpl ;
1415import org .springframework .data .domain .Pageable ;
16+ import org .springframework .data .support .PageableExecutionUtils ;
1517import org .springframework .stereotype .Repository ;
1618
1719import java .util .List ;
@@ -50,48 +52,56 @@ public Page<EmotionRecord> findByLoginId(String loginId, Pageable pageable) {
5052 .join (QEmotionRecord .emotionRecord .user , QUser .user ).fetchJoin ()
5153 .join (QEmotionRecord .emotionRecord .spotifyMusic , QSpotifyMusic .spotifyMusic ).fetchJoin ()
5254 .where (QUser .user .loginId .eq (loginId ))
55+ .orderBy (QEmotionRecord .emotionRecord .createdAt .desc ())
5356 .offset (pageable .getOffset ())
5457 .limit (pageable .getPageSize ())
5558 .fetch ();
5659
5760 // Spring Data JPA에서 페이징 처리를 위한 메서드 사용 시,
5861 // 내부적으로 데이터(페이징된 결과)를 가져오는 쿼리와 전체 데이터 수를 계산하는 쿼리가 둘 다 실행됨
5962 // QueryDSL을 사용할 경우에 위와 달리 데이터 수 계산 쿼리를 별도로 실행해 줘야함 (Querydsl 5 이상 권장 방식)
60- long total = Optional . ofNullable (
61- jpaQueryFactory
62- . select ( QEmotionRecord . emotionRecord . count ())
63- . from (QEmotionRecord .emotionRecord )
64- . join (QEmotionRecord .emotionRecord . user , QUser . user )
65- . where ( QUser . user . loginId . eq ( loginId ) )
66- . fetchOne ( )
67- ). orElse ( 0L );
68-
69- return new PageImpl <>( emotionRecords , pageable , total );
63+ return PageableExecutionUtils . getPage ( emotionRecords , pageable , () ->
64+ Optional . ofNullable (
65+ jpaQueryFactory
66+ . select (QEmotionRecord .emotionRecord . count () )
67+ . from (QEmotionRecord .emotionRecord )
68+ . join ( QEmotionRecord . emotionRecord . user , QUser . user )
69+ . where ( QUser . user . loginId . eq ( loginId ) )
70+ . fetchOne ()
71+ ). orElse ( 0L )
72+ );
7073 }
7174
72- // 로그인 된 userId를 제외한 EmotionRecord 조회 (LEFT JOIN으로 spotifyMusic 포함) 후 페이징처리
73- @ Override
74- public Page <EmotionRecord > findByWithoutUserId (Long userId , Pageable pageable ) {
75+ // 동적으로 필터링 후 EmotionRecords를 가져오는 쿼리
76+ public Page <EmotionRecord > findByFilters (Long userId , List <Emotions > emotions , String spotifyId , Pageable pageable ) {
7577 List <EmotionRecord > emotionRecords = jpaQueryFactory
7678 .selectFrom (QEmotionRecord .emotionRecord )
7779 .join (QEmotionRecord .emotionRecord .user , QUser .user ).fetchJoin ()
7880 .leftJoin (QEmotionRecord .emotionRecord .spotifyMusic , QSpotifyMusic .spotifyMusic ).fetchJoin ()
79- .where (QUser .user .userId .ne (userId ))
81+ .where (
82+ excludeUserId (userId ),
83+ filterByEmotions (emotions ),
84+ filterBySpotifyId (spotifyId )
85+ )
86+ .orderBy (QEmotionRecord .emotionRecord .createdAt .desc ())
8087 .offset (pageable .getOffset ())
8188 .limit (pageable .getPageSize ())
8289 .fetch ();
8390
8491 // 위의 findByLoginId 메서드 설명 참고
85- long total = Optional .ofNullable (
86- jpaQueryFactory
87- .select (QEmotionRecord .emotionRecord .count ())
88- .from (QEmotionRecord .emotionRecord )
89- .join (QEmotionRecord .emotionRecord .user , QUser .user )
90- .where (QUser .user .userId .ne (userId ))
91- .fetchOne ()
92- ).orElse (0L );
93-
94- return new PageImpl <>(emotionRecords , pageable , total );
92+ return PageableExecutionUtils .getPage (emotionRecords , pageable , () ->
93+ Optional .ofNullable (
94+ jpaQueryFactory
95+ .select (QEmotionRecord .emotionRecord .count ())
96+ .from (QEmotionRecord .emotionRecord )
97+ .join (QEmotionRecord .emotionRecord .user , QUser .user )
98+ .where (
99+ excludeUserId (userId ), // 로그인 된 userId를 제외한 EmotionRecord 조회
100+ filterByEmotions (emotions ), // 감정이 있을 경우
101+ filterBySpotifyId (spotifyId ) // spotifyId 있을 경우
102+ )
103+ .fetchOne ()
104+ ).orElse (0L ));
95105 }
96106
97107 // recordId에 해당하는 EmotionRecord 조회
@@ -107,9 +117,21 @@ public Optional<EmotionRecord> findByRecordId(Long recordId) {
107117 // recordId에 해당하는 EmotionRecord 삭제
108118 @ Override
109119 public int deleteByRecordId (Long recordId ) {
110- return (int )jpaQueryFactory
120+ return (int ) jpaQueryFactory
111121 .delete (QEmotionRecord .emotionRecord )
112122 .where (QEmotionRecord .emotionRecord .recordId .eq (recordId ))
113123 .execute ();
114124 }
125+
126+ private BooleanExpression excludeUserId (Long userId ) {
127+ return userId != null ? QUser .user .userId .ne (userId ) : null ;
128+ }
129+
130+ private BooleanExpression filterByEmotions (List <Emotions > emotions ) {
131+ return (emotions != null && !emotions .isEmpty ()) ? QEmotionRecord .emotionRecord .emotion .in (emotions ) : null ;
132+ }
133+
134+ private BooleanExpression filterBySpotifyId (String spotifyId ) {
135+ return (spotifyId != null && !spotifyId .isBlank ()) ? QSpotifyMusic .spotifyMusic .spotifyId .eq (spotifyId ) : null ;
136+ }
115137}
0 commit comments