|
10 | 10 | import com.example.wini.domain.note.domain.SortOrder; |
11 | 11 | import com.example.wini.domain.template.domain.ActionCategory; |
12 | 12 | import com.example.wini.domain.template.domain.EmotionType; |
| 13 | +import com.querydsl.core.Tuple; |
13 | 14 | import com.querydsl.core.types.Order; |
14 | 15 | import com.querydsl.core.types.OrderSpecifier; |
15 | | -import com.querydsl.core.types.Projections; |
16 | | -import com.querydsl.core.types.dsl.BooleanExpression; |
17 | | -import com.querydsl.core.types.dsl.CaseBuilder; |
18 | | -import com.querydsl.core.types.dsl.NumberExpression; |
| 16 | +import com.querydsl.core.types.dsl.*; |
19 | 17 | import com.querydsl.jpa.impl.JPAQueryFactory; |
20 | 18 | import java.time.DayOfWeek; |
21 | 19 | import java.time.LocalDate; |
22 | 20 | import java.time.LocalDateTime; |
23 | 21 | import java.time.temporal.TemporalAdjusters; |
24 | 22 | import java.util.ArrayList; |
| 23 | +import java.util.Comparator; |
25 | 24 | import java.util.List; |
26 | 25 | import java.util.Optional; |
27 | 26 | import lombok.RequiredArgsConstructor; |
@@ -73,41 +72,63 @@ public List<Note> findSavedNotesSortedByCreatedAt(Long memberId, Long roomId, So |
73 | 72 | @Override |
74 | 73 | public ActionChange findMostIncreasedPositiveActionChange(Long memberId, Long roomId) { |
75 | 74 | LocalDate today = LocalDate.now(); |
76 | | - NumberExpression<Long> thisMonthNotes = countThisMonthNotes(today); |
77 | | - NumberExpression<Long> lastMonthNotes = countLastMonthNotes(today); |
78 | | - NumberExpression<Long> increaseCount = thisMonthNotes.subtract(lastMonthNotes); |
79 | 75 |
|
80 | | - return queryFactory |
81 | | - .select(Projections.constructor(ActionChange.class, action, increaseCount)) |
| 76 | + NumberExpression<Integer> rawChange = new CaseBuilder() |
| 77 | + .when(isCreatedThisMonth(today)) |
| 78 | + .then(1) |
| 79 | + .when(isCreatedLastMonth(today)) |
| 80 | + .then(-1) |
| 81 | + .otherwise(0); |
| 82 | + |
| 83 | + NumberExpression<Long> monthlyChange = rawChange.castToNum(Long.class); |
| 84 | + NumberExpression<Long> monthlyChangeSum = monthlyChange.sumLong().coalesce(0L); |
| 85 | + |
| 86 | + List<Tuple> results = queryFactory |
| 87 | + .select(action, monthlyChangeSum) |
82 | 88 | .from(note) |
83 | 89 | .join(note.action, action) |
84 | 90 | .join(action.actionCategory, actionCategory) |
85 | 91 | .where(isThisRoom(roomId) |
86 | 92 | .and(isReceiver(memberId)) |
87 | 93 | .and(actionCategory.emotionType.eq(EmotionType.POSITIVE))) |
88 | | - .groupBy(action) |
89 | | - .orderBy(increaseCount.desc()) |
90 | | - .fetchFirst(); |
| 94 | + .groupBy(action.id) |
| 95 | + .fetch(); |
| 96 | + |
| 97 | + return results.stream() |
| 98 | + .map(t -> new ActionChange(t.get(action), t.get(monthlyChangeSum))) |
| 99 | + .max(Comparator.comparing(ActionChange::monthlyChange)) |
| 100 | + .orElse(null); |
91 | 101 | } |
92 | 102 |
|
93 | 103 | @Override |
94 | 104 | public ActionChange findMostDecreasedNegativeActionChange(Long memberId, Long roomId) { |
95 | 105 | LocalDate today = LocalDate.now(); |
96 | | - NumberExpression<Long> thisMonthNotes = countThisMonthNotes(today); |
97 | | - NumberExpression<Long> lastMonthNotes = countLastMonthNotes(today); |
98 | | - NumberExpression<Long> decreaseCount = thisMonthNotes.subtract(lastMonthNotes); |
99 | 106 |
|
100 | | - return queryFactory |
101 | | - .select(Projections.constructor(ActionChange.class, action, decreaseCount)) |
| 107 | + NumberExpression<Integer> rawChange = new CaseBuilder() |
| 108 | + .when(isCreatedThisMonth(today)) |
| 109 | + .then(1) |
| 110 | + .when(isCreatedLastMonth(today)) |
| 111 | + .then(-1) |
| 112 | + .otherwise(0); |
| 113 | + |
| 114 | + NumberExpression<Long> monthlyChange = rawChange.castToNum(Long.class); |
| 115 | + NumberExpression<Long> monthlyChangeSum = monthlyChange.sumLong().coalesce(0L); |
| 116 | + |
| 117 | + List<Tuple> results = queryFactory |
| 118 | + .select(action, monthlyChangeSum) |
102 | 119 | .from(note) |
103 | 120 | .join(note.action, action) |
104 | 121 | .join(action.actionCategory, actionCategory) |
105 | 122 | .where(isThisRoom(roomId) |
106 | 123 | .and(isReceiver(memberId)) |
107 | 124 | .and(actionCategory.emotionType.eq(EmotionType.NEGATIVE))) |
108 | | - .groupBy(action) |
109 | | - .orderBy(decreaseCount.asc()) |
110 | | - .fetchFirst(); |
| 125 | + .groupBy(action.id) |
| 126 | + .fetch(); |
| 127 | + |
| 128 | + return results.stream() |
| 129 | + .map(t -> new ActionChange(t.get(action), t.get(monthlyChangeSum))) |
| 130 | + .min(Comparator.comparing(ActionChange::monthlyChange)) |
| 131 | + .orElse(null); |
111 | 132 | } |
112 | 133 |
|
113 | 134 | @Override |
@@ -190,32 +211,23 @@ public Long countTotalNotesExchanged(Long roomId) { |
190 | 211 | .fetchFirst(); |
191 | 212 | } |
192 | 213 |
|
193 | | - private NumberExpression<Long> countThisMonthNotes(LocalDate today) { |
194 | | - LocalDateTime startOfThisMonth = today.withDayOfMonth(1).atStartOfDay(); |
195 | | - LocalDateTime endOfThisMonth = today.plusDays(1).atStartOfDay(); |
| 214 | + private BooleanExpression isCreatedThisMonth(LocalDate today) { |
| 215 | + LocalDate firstDayOfThisMonth = today.withDayOfMonth(1); |
| 216 | + |
| 217 | + LocalDateTime startOfThisMonth = firstDayOfThisMonth.atStartOfDay(); |
| 218 | + LocalDateTime endOfThisMonth = firstDayOfThisMonth.plusMonths(1).atStartOfDay(); |
196 | 219 |
|
197 | | - return new CaseBuilder() |
198 | | - .when(note.createdAt.goe(startOfThisMonth).and(note.createdAt.lt(endOfThisMonth))) |
199 | | - .then(1L) |
200 | | - .otherwise(0L) |
201 | | - .sum(); |
| 220 | + return note.createdAt.goe(startOfThisMonth).and(note.createdAt.lt(endOfThisMonth)); |
202 | 221 | } |
203 | 222 |
|
204 | | - private NumberExpression<Long> countLastMonthNotes(LocalDate today) { |
205 | | - LocalDate lastMonthOfToday = today.minusMonths(1); |
| 223 | + private BooleanExpression isCreatedLastMonth(LocalDate today) { |
| 224 | + LocalDate firstDayOfThisMonth = today.withDayOfMonth(1); |
| 225 | + LocalDate firstDayOfLastMonth = firstDayOfThisMonth.minusMonths(1); |
206 | 226 |
|
207 | | - LocalDateTime startOfLastMonth = lastMonthOfToday.withDayOfMonth(1).atStartOfDay(); |
208 | | - LocalDateTime endOfLastMonth = lastMonthOfToday.plusDays(1).atStartOfDay(); |
209 | | - if (today.getDayOfMonth() == today.lengthOfMonth()) { |
210 | | - endOfLastMonth = |
211 | | - lastMonthOfToday.with(TemporalAdjusters.lastDayOfMonth()).atStartOfDay(); |
212 | | - } |
| 227 | + LocalDateTime startOfLastMonth = firstDayOfLastMonth.atStartOfDay(); |
| 228 | + LocalDateTime endOfLastMonth = firstDayOfThisMonth.atStartOfDay(); |
213 | 229 |
|
214 | | - return new CaseBuilder() |
215 | | - .when(note.createdAt.goe(startOfLastMonth).and(note.createdAt.lt(endOfLastMonth))) |
216 | | - .then(1L) |
217 | | - .otherwise(0L) |
218 | | - .sum(); |
| 230 | + return note.createdAt.goe(startOfLastMonth).and(note.createdAt.lt(endOfLastMonth)); |
219 | 231 | } |
220 | 232 |
|
221 | 233 | private BooleanExpression isCreatedLatest() { |
|
0 commit comments