Skip to content

Commit 78cc887

Browse files
committed
refactor: 사용자가 좋아요 눌렀는지 여부를 확인 하는 영역에서 N+1문제 해결
1 parent 8aaed03 commit 78cc887

File tree

4 files changed

+79
-12
lines changed

4 files changed

+79
-12
lines changed

lime-domain/src/main/java/com/programmers/lime/domains/feed/implementation/FeedCursorReader.java

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.programmers.lime.domains.feed.implementation;
22

33
import java.util.List;
4+
import java.util.Set;
5+
import java.util.stream.Collectors;
46

57
import org.springframework.stereotype.Component;
68

@@ -10,6 +12,7 @@
1012
import com.programmers.lime.common.model.Hobby;
1113
import com.programmers.lime.domains.feed.model.FeedCursorSummary;
1214
import com.programmers.lime.domains.feed.model.FeedCursorSummaryLike;
15+
import com.programmers.lime.domains.feed.model.FeedLikeInfo;
1316
import com.programmers.lime.domains.feed.model.FeedSortCondition;
1417
import com.programmers.lime.domains.feed.repository.FeedLikeRepository;
1518
import com.programmers.lime.domains.feed.repository.FeedRepository;
@@ -26,8 +29,6 @@ public class FeedCursorReader {
2629

2730
private final FeedRepository feedRepository;
2831
private final MemberReader memberReader;
29-
private final FeedLikeRepository feedLikeRepository;
30-
private final FeedReader feedReader;
3132

3233
public CursorSummary<FeedCursorSummaryLike> getFeedByCursor(
3334
final Hobby hobby,
@@ -47,18 +48,33 @@ public CursorSummary<FeedCursorSummaryLike> getFeedByCursor(
4748
pageSize
4849
);
4950

50-
List<FeedCursorSummaryLike> feedCursorSummaryLikes = feedCursorSummaries.stream().map(
51-
feedCursorSummary -> {
52-
boolean isLike = feedLikeRepository.existsByMemberIdAndFeed(
53-
loginMemberId,
54-
feedReader.read(feedCursorSummary.feedId())
55-
);
51+
List<FeedCursorSummaryLike> feedCursorSummaryLikes = getFeedCursorSummaryLikes(
52+
loginMemberId,
53+
feedCursorSummaries
54+
);
55+
56+
return CursorUtils.getCursorSummaries(feedCursorSummaryLikes);
57+
}
58+
59+
private List<FeedCursorSummaryLike> getFeedCursorSummaryLikes(
60+
final Long loginMemberId,
61+
final List<FeedCursorSummary> feedCursorSummaries
62+
) {
63+
List<Long> feedIds = feedCursorSummaries.stream()
64+
.map(FeedCursorSummary::feedId)
65+
.toList();
66+
67+
Set<Long> feedLikeInfoSet = feedRepository.getFeedLikeInfos(feedIds, loginMemberId)
68+
.stream()
69+
.map(FeedLikeInfo::feedId)
70+
.collect(Collectors.toSet());
5671

72+
return feedCursorSummaries.stream().map(
73+
feedCursorSummary -> {
74+
boolean isLike = feedLikeInfoSet.contains(feedCursorSummary.feedId());
5775
return feedCursorSummary.of(isLike);
5876
}
5977
).toList();
60-
61-
return CursorUtils.getCursorSummaries(feedCursorSummaryLikes);
6278
}
6379

6480
private int getPageSizeByParameter(final CursorPageParameters parameters) {
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
package com.programmers.lime.domains.feed.model;
2+
3+
public record FeedLikeInfo(
4+
Long feedId,
5+
Long memberId
6+
7+
) {
8+
}

lime-domain/src/main/java/com/programmers/lime/domains/feed/repository/FeedRepositoryForCursor.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
import com.programmers.lime.common.model.Hobby;
66
import com.programmers.lime.domains.feed.model.FeedCursorSummary;
7-
import com.programmers.lime.domains.feed.model.FeedCursorSummaryLike;
7+
import com.programmers.lime.domains.feed.model.FeedLikeInfo;
88
import com.programmers.lime.domains.feed.model.FeedSortCondition;
99

1010
public interface FeedRepositoryForCursor {
@@ -15,4 +15,9 @@ List<FeedCursorSummary> findAllByCursor(
1515
final String cursorId,
1616
final int pageSize
1717
);
18+
19+
List<FeedLikeInfo> getFeedLikeInfos(
20+
final List<Long> feedIds,
21+
final Long loginMemberId
22+
);
1823
}

lime-domain/src/main/java/com/programmers/lime/domains/feed/repository/FeedRepositoryForCursorImpl.java

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
import static com.programmers.lime.domains.feed.domain.QFeed.*;
44
import static com.programmers.lime.domains.feed.domain.QFeedItem.*;
5+
import static com.programmers.lime.domains.feed.domain.QFeedLike.*;
56
import static com.programmers.lime.domains.member.domain.QMember.*;
67
import static com.querydsl.core.group.GroupBy.*;
78

@@ -12,11 +13,13 @@
1213
import com.programmers.lime.domains.feed.model.FeedCursorItem;
1314
import com.programmers.lime.domains.feed.model.FeedCursorSummary;
1415
import com.programmers.lime.domains.feed.model.FeedCursorSummaryLike;
16+
import com.programmers.lime.domains.feed.model.FeedLikeInfo;
1517
import com.programmers.lime.domains.feed.model.FeedSortCondition;
1618
import com.programmers.lime.domains.member.model.MemberInfo;
1719
import com.querydsl.core.types.ConstantImpl;
1820
import com.querydsl.core.types.Order;
1921
import com.querydsl.core.types.OrderSpecifier;
22+
import com.querydsl.core.types.Predicate;
2023
import com.querydsl.core.types.Projections;
2124
import com.querydsl.core.types.dsl.BooleanExpression;
2225
import com.querydsl.core.types.dsl.Expressions;
@@ -32,6 +35,15 @@ public class FeedRepositoryForCursorImpl implements FeedRepositoryForCursor {
3235

3336
private final JPAQueryFactory jpaQueryFactory;
3437

38+
private static BooleanExpression eqHobby(final Hobby hobby) {
39+
40+
if (hobby == null) {
41+
return null;
42+
}
43+
44+
return feed.hobby.eq(hobby);
45+
}
46+
3547
public List<FeedCursorSummary> findAllByCursor(
3648
final Long nicknameMemberId,
3749
final Hobby hobby,
@@ -42,7 +54,7 @@ public List<FeedCursorSummary> findAllByCursor(
4254
List<Long> feedIds = jpaQueryFactory.select(feed.id)
4355
.from(feed)
4456
.where(
45-
feed.hobby.eq(hobby),
57+
eqHobby(hobby),
4658
eqMemberId(nicknameMemberId),
4759
lessThanNextCursorId(feedSortCondition, cursorId)
4860
).orderBy(feedSort(feedSortCondition), feed.id.desc())
@@ -86,6 +98,32 @@ public List<FeedCursorSummary> findAllByCursor(
8698
);
8799
}
88100

101+
@Override
102+
public List<FeedLikeInfo> getFeedLikeInfos(
103+
final List<Long> feedIds,
104+
final Long loginMemberId
105+
) {
106+
return jpaQueryFactory
107+
.select(
108+
Projections.constructor(
109+
FeedLikeInfo.class,
110+
feedLike.feed.id,
111+
feedLike.memberId
112+
)
113+
)
114+
.from(feedLike)
115+
.where(feedLike.feed.id.in(feedIds), eqLoginMemberIdWithFeedLikes(loginMemberId))
116+
.fetch();
117+
}
118+
119+
private Predicate eqLoginMemberIdWithFeedLikes(final Long loginMemberId) {
120+
if (loginMemberId == null) {
121+
return null;
122+
}
123+
124+
return feedLike.memberId.eq(loginMemberId);
125+
}
126+
89127
private BooleanExpression eqMemberId(
90128
final Long nicknameMemberId
91129
) {

0 commit comments

Comments
 (0)