내가 레거시를 낳았다…
현재 코드는 유지보수 관점을 떠나서, 네이밍, 가독성 측면에서도 너무 안좋은 코드임을 인지하고 있습니다.
제가 생각한 로직을 공유하고, 인지하고 있는 문제점, 그리고 윌리엄이 남겨주신 피드백의 대한 생각 및 공유로 작성해보겠습니다. 리팩터 후에 메모도 따로 남길게요!
우선 일일 상세내역을 조회하기 위해서
저희가 필요한 테이블은 expenditure와 income입니다.
제가 여기서 겪었던 문제는 income과 expenditure에 대해서 페이징 처리가 아니라
일일 상세내역에 대한 페이징을 작성해야한다는 것
이었어요.expenditure와 income의 날짜의 합집합에 해당하는 일일 상세 내역을 보여주어야합니다.
20~11일에 대한 상세내역을 보여주어야합니다.
고민
차피 한달을 10일씩 자르면 페이징이 최대 4개(31일) 보통 3개(30,29,28)로 짤리니까 그냥 고정된 날짜로 짜를까했는데!!!
, 이경우 유저가 30~21일 중 30일만 작성했다면… 30일에 데이터만 볼 수 있어요.. 그리고 페이징의 개념과 맞지 않는다고 생각했습니다.querydsl과 jpa는 union을 지원하지 않습니다 …
2022-08월에 작성한 expenditure와 income의 모든 날짜를 불러온 후 합집합하였습니다.
private List<LocalDate> getPageDate(PageCustomRequest pageCustomRequest, Long userId, LocalDate date) {
long offset = pageCustomRequest.getOffset();
int size = pageCustomRequest.getSize();
int year = date.getYear();
int month = date.getMonthValue();
List<LocalDateTime> expenditureTimes = queryFactory.select(expenditure.registerDate)
.from(expenditure)
.where(
expenditure.user.id.eq(userId),
expenditure.registerDate.year().eq(year),
expenditure.registerDate.month().eq(month)
)
.fetch();
List<LocalDateTime> incomeTimes = queryFactory.select(income.registerDate)
.from(income)
.where(
income.user.id.eq(userId),
income.registerDate.year().eq(year),
income.registerDate.month().eq(month)
)
.fetch();
List<LocalDate> expenditureDate = expenditureTimes.stream()
.map(LocalDateTime::toLocalDate)
.collect(Collectors.toList());
List<LocalDate> incomeDate = incomeTimes.stream()
.map(LocalDateTime::toLocalDate)
.collect(Collectors.toList());
expenditureDate.addAll(incomeDate);
List<LocalDate> dates = expenditureDate.stream()
.distinct()
.collect(Collectors.toList());
Collections.sort(dates, (d1, d2) -> d1.isAfter(d2) ? -1 : 1);
int end = (int)offset + size > dates.size() ? dates.size() : (int)offset + size;
return dates.subList(((int)offset), end);
}
union이 지원안되니까 native쿼리로 불러와서 정렬한다.
가장 최악 - 개선 무조건…
public PageCustomImpl<FindDayAccountResponse> findDailyAccount(Long userId, PageCustomRequest pageRequest,
LocalDate date) {
List<LocalDate> dates = getPageDate(pageRequest, userId, date);
List<FindDayAccountResponse> responses = new ArrayList<>();
dates.iterator().forEachRemaining(
d -> responses.add(new FindDayAccountResponse(d, getDayIncomeAmount(d), getDayExpenditureAmount(d),
getDayDetails(userId, d)))
);
Collections.sort(responses,
(o1, o2) -> o2.getRegisterDate().getDayOfMonth() - o1.getRegisterDate().getDayOfMonth());
return new PageCustomImpl<>(pageRequest.getPage(), pageRequest, responses);
}