Skip to content

Commit e817ea0

Browse files
authored
Merge pull request #30 from prgrms-web-devcourse-final-project/feat/emotionRecord/main
refactor: EmotionRecord JPQL -> QueryDSL 리팩토링
2 parents f83a904 + 492e162 commit e817ea0

File tree

5 files changed

+100
-32
lines changed

5 files changed

+100
-32
lines changed

src/main/java/org/dfbf/soundlink/domain/emotionRecord/dto/response/EmotionRecordUpdateResponseDTO.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
public record EmotionRecordUpdateResponseDTO(
66
Long recordId,
7-
Long spotifyId,
7+
String spotifyId,
88
String title,
99
String artist,
1010
String albumImage,
@@ -14,7 +14,7 @@ public record EmotionRecordUpdateResponseDTO(
1414
public static EmotionRecordUpdateResponseDTO fromEntity(EmotionRecord record) {
1515
return new EmotionRecordUpdateResponseDTO(
1616
record.getRecordId(),
17-
record.getSpotifyMusic().getSpotifyId(),
17+
String.valueOf(record.getSpotifyMusic().getSpotifyId()),
1818
record.getSpotifyMusic().getTitle(),
1919
record.getSpotifyMusic().getArtist(),
2020
record.getSpotifyMusic().getAlbumImage(),

src/main/java/org/dfbf/soundlink/domain/emotionRecord/dto/response/SpotifyMusicResponseDTO.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@
22

33
import org.dfbf.soundlink.domain.emotionRecord.entity.SpotifyMusic;
44

5-
public record SpotifyMusicResponseDTO(Long spotifyId, String title, String artist, String albumImage) {
5+
public record SpotifyMusicResponseDTO(String spotifyId, String title, String artist, String albumImage) {
66
public static SpotifyMusicResponseDTO fromEntity(SpotifyMusic music) {
77
return new SpotifyMusicResponseDTO(
8-
music.getSpotifyId(),
8+
String.valueOf(music.getSpotifyId()),
99
music.getTitle(),
1010
music.getArtist(),
1111
music.getAlbumImage()

src/main/java/org/dfbf/soundlink/domain/emotionRecord/repository/EmotionRecordRepository.java

Lines changed: 6 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,44 +2,22 @@
22

33
import org.dfbf.soundlink.domain.emotionRecord.entity.EmotionRecord;
44
import org.dfbf.soundlink.domain.emotionRecord.repository.dsl.EmotionRecordRepositoryCustom;
5-
import org.dfbf.soundlink.domain.user.dto.response.EmotionRecordDto;
65
import org.dfbf.soundlink.domain.user.entity.User;
7-
import org.springframework.data.domain.Page;
8-
import org.springframework.data.domain.Pageable;
96
import org.springframework.data.jpa.repository.*;
107
import org.springframework.data.repository.query.Param;
118
import org.springframework.stereotype.Repository;
129

13-
import java.util.List;
14-
import java.util.Optional;
15-
1610
@Repository
1711
public interface EmotionRecordRepository extends JpaRepository<EmotionRecord, Long>, EmotionRecordRepositoryCustom {
1812

1913
@Modifying(clearAutomatically = true)
2014
@Query("DELETE FROM EmotionRecord e WHERE e.user = :user")
21-
public void deleteByUser(@Param("user") User user);
22-
23-
@Query("SELECT er FROM EmotionRecord er " +
24-
"JOIN FETCH er.user u " +
25-
"JOIN FETCH er.spotifyMusic sm " +
26-
"WHERE u.loginId = :loginId")
27-
Page<EmotionRecord> findByLoginId(@Param("loginId") String loginId, Pageable pageable);
28-
29-
@Query("SELECT er FROM EmotionRecord er " +
30-
"JOIN FETCH er.user u " +
31-
"LEFT JOIN FETCH er.spotifyMusic sm " +
32-
"WHERE u.userId <> :userId ")
33-
Page<EmotionRecord> findByWithoutUserId(@Param("userId") Long userId, Pageable pageable);
34-
35-
Optional<EmotionRecord> findByRecordId(@Param("recordId") Long recordId);
36-
37-
@Modifying
38-
int deleteByRecordId(@Param("recordId") Long recordId);
15+
void deleteByUser(@Param("user") User user);
3916
}
4017

41-
/**
42-
* @Modifying(clearAutomatically = true)
43-
* 1차 캐시안의 내용까지 지워버리는 옵션
44-
*/
18+
/*
19+
@Modifying(clearAutomatically = true)
20+
1차 캐시안의 내용까지 지워버리는 옵션
21+
*/
22+
4523

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
11
package org.dfbf.soundlink.domain.emotionRecord.repository.dsl;
22

3+
import org.dfbf.soundlink.domain.emotionRecord.entity.EmotionRecord;
34
import org.dfbf.soundlink.domain.user.dto.response.EmotionRecordDto;
45
import org.dfbf.soundlink.domain.user.entity.User;
6+
import org.springframework.data.domain.Page;
7+
import org.springframework.data.domain.Pageable;
58

69
import java.util.List;
10+
import java.util.Optional;
711

812
public interface EmotionRecordRepositoryCustom {
913

1014
List<EmotionRecordDto> findByUser(User user);
15+
16+
Page<EmotionRecord> findByLoginId(String loginId, Pageable pageable);
17+
18+
Page<EmotionRecord> findByWithoutUserId(Long userId, Pageable pageable);
19+
20+
Optional<EmotionRecord> findByRecordId(Long recordId);
21+
22+
int deleteByRecordId(Long recordId);
1123
}

src/main/java/org/dfbf/soundlink/domain/emotionRecord/repository/dsl/EmotionRecordRepositoryImpl.java

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,19 @@
33
import com.querydsl.core.types.Projections;
44
import com.querydsl.jpa.impl.JPAQueryFactory;
55
import lombok.RequiredArgsConstructor;
6+
import org.dfbf.soundlink.domain.emotionRecord.entity.EmotionRecord;
67
import org.dfbf.soundlink.domain.emotionRecord.entity.QEmotionRecord;
8+
import org.dfbf.soundlink.domain.emotionRecord.entity.QSpotifyMusic;
79
import org.dfbf.soundlink.domain.user.dto.response.EmotionRecordDto;
10+
import org.dfbf.soundlink.domain.user.entity.QUser;
811
import org.dfbf.soundlink.domain.user.entity.User;
12+
import org.springframework.data.domain.Page;
13+
import org.springframework.data.domain.PageImpl;
14+
import org.springframework.data.domain.Pageable;
915
import org.springframework.stereotype.Repository;
1016

1117
import java.util.List;
18+
import java.util.Optional;
1219

1320
@Repository
1421
@RequiredArgsConstructor
@@ -34,4 +41,75 @@ public List<EmotionRecordDto> findByUser(User user) {
3441
.fetch();
3542

3643
}
44+
45+
// loginId를 기준으로 JOIN FETCH (user, spotifyMusic) 후 페이징 처리
46+
@Override
47+
public Page<EmotionRecord> findByLoginId(String loginId, Pageable pageable) {
48+
List<EmotionRecord> emotionRecords = jpaQueryFactory
49+
.selectFrom(QEmotionRecord.emotionRecord)
50+
.join(QEmotionRecord.emotionRecord.user, QUser.user).fetchJoin()
51+
.join(QEmotionRecord.emotionRecord.spotifyMusic, QSpotifyMusic.spotifyMusic).fetchJoin()
52+
.where(QUser.user.loginId.eq(loginId))
53+
.offset(pageable.getOffset())
54+
.limit(pageable.getPageSize())
55+
.fetch();
56+
57+
// Spring Data JPA에서 페이징 처리를 위한 메서드 사용 시,
58+
// 내부적으로 데이터(페이징된 결과)를 가져오는 쿼리와 전체 데이터 수를 계산하는 쿼리가 둘 다 실행됨
59+
// 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);
70+
}
71+
72+
// 로그인 된 userId를 제외한 EmotionRecord 조회 (LEFT JOIN으로 spotifyMusic 포함) 후 페이징처리
73+
@Override
74+
public Page<EmotionRecord> findByWithoutUserId(Long userId, Pageable pageable) {
75+
List<EmotionRecord> emotionRecords = jpaQueryFactory
76+
.selectFrom(QEmotionRecord.emotionRecord)
77+
.join(QEmotionRecord.emotionRecord.user, QUser.user).fetchJoin()
78+
.leftJoin(QEmotionRecord.emotionRecord.spotifyMusic, QSpotifyMusic.spotifyMusic).fetchJoin()
79+
.where(QUser.user.userId.ne(userId))
80+
.offset(pageable.getOffset())
81+
.limit(pageable.getPageSize())
82+
.fetch();
83+
84+
// 위의 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);
95+
}
96+
97+
// recordId에 해당하는 EmotionRecord 조회
98+
@Override
99+
public Optional<EmotionRecord> findByRecordId(Long recordId) {
100+
EmotionRecord emotionRecord = jpaQueryFactory
101+
.selectFrom(QEmotionRecord.emotionRecord)
102+
.where(QEmotionRecord.emotionRecord.recordId.eq(recordId))
103+
.fetchOne();
104+
return Optional.ofNullable(emotionRecord);
105+
}
106+
107+
// recordId에 해당하는 EmotionRecord 삭제
108+
@Override
109+
public int deleteByRecordId(Long recordId) {
110+
return (int)jpaQueryFactory
111+
.delete(QEmotionRecord.emotionRecord)
112+
.where(QEmotionRecord.emotionRecord.recordId.eq(recordId))
113+
.execute();
114+
}
37115
}

0 commit comments

Comments
 (0)