Projects/[Spring] Code Refactoring Project

[Spring Plus] JPQL로 쿼리 옵션 추가하기

montmer27 2026. 2. 27. 23:06
문제 요약

기획자의 긴급 요청이 왔어요! 아래의 요구사항에 맞춰 기획 요건에 대응할 수 있는 코드를 작성해주세요. 

  • 할 일 검색 시 weather 조건으로도 검색할 수 있어야해요.
    • weather 조건은 있을 수도 있고, 없을 수도 있어요!
  • 할 일 검색 시 수정일 기준으로 기간 검색이 가능해야해요.
    • 기간의 시작과 끝 조건은 있을 수도 있고, 없을 수도 있어요!
  • JPQL을 사용하고, 쿼리 메소드명은 자유롭게 지정하되 너무 길지 않게 해주세요.

 

문제 접근

weather, 수정일 모두 선택 사항이므로 @RequestParam(required = false) 옵션으로 Service에 전달해야겠다.

HTTP 요청의 쿼리 파라미터는 전부 문자열이므로, String 타입으로 전달한 뒤 LocalDateTime 형식으로 변환해줘야겠다. 

 

해결 방법 요약

1. TodoController.getTodos() -> String 타입으로 weather, startDate, endDate 파라미터 추가

2. TodoService.getTodos() -> 시그니처 변경, String 타입의 startDate와 endDate를 LocalDateTime 타입으로 변경하여 쿼리 메서드 실행

3. TodoRepository -> 다른 쿼리 메서드 참고하여 findAllByWeatherOrModifiedAt() 쿼리 메서드 생성

 

해결 방법 상세

TodoController.getTodos() -> String 타입으로 weather, startDate, endDate 파라미터 추가

TodoController.java

2. TodoService.getTodos() -> 시그니처 변경, String 타입의 startDate와 endDate를 LocalDateTime 타입으로 변경하여 쿼리 메서드 실행

TodoServce.java

3. TodoRepository -> 다른 쿼리 메서드 참고하여 findAllByWeatherOrModifiedAt() 쿼리 메서드 생성

modifiedAt()을 기준으로 최신 순으로 정렬

TodoRepository.java

결과

아래와 같이 데이터를 만들었다.

날씨가 "흐림"이고 2026-02-19T10:15:30 이전의 데이터만 가져오도록 해보자.

실행을 해보면 weather와 endDate가 파라미터에 잘 담겼다.

endDate는 LocalDateTime 형식의 end라는 변수로 변환된 뒤, findAllByWeatherOrModifiedAt()에 파라미터로 들어간다.

아래와 같이 날씨와 날짜 정보가 잘 반영된 결과가 반환된다.

개선

날짜를 LocalDateTime 형식으로 보내기가 고객 입장에서 번거로울 것 같다. 날짜만 보내면 내부적으로 해당 날짜의 00시 00분 00초 또는 23시 59분 59초로 변환하여 계산하도록 로직을 수정해보자.

접근 - 개선

2026-02-27과 같은 형식은 LocalDate 형식이므로 전달받은 문자열에 00시 00분 00초라는 시간을 붙여 LocalDateTime으로 변환시켜줘야 한다. 

Idea: startDate는 00시 00분부터 포함하도록 하고, endDate는 23시 59분 59초까지 포함하도록 해 보자.

 

데이터를 아래와 같이 준비하고(주의: 하나는 2027-02-28 00:00:01에 수정)

아래와 같이 API 요청을 보내면 2월 27일 이전까지의 데이터 3개가 모두 조회된다.

 

주의: LocalTime.MAX는 다음날 00:00:00까지도 포함한다.

만약 id=4인 데이터가 아래와 같았더라면

 

endDate를 02-27로 설정했음에도 같이 조회된다.

 

인사이트
Http 요청의 쿼리 파라미터는 모두 String이라는 점을 다시 환기하게 되었고, 덕분에
LocalDate, LocalDateTime.parse(String date)를 통해서 문자열을 LocalDate 또는 LocalDateTime 형태로 바꿀 수 있다는 것을 알았다.
또한 사용자의 입장에서 검색 조건으로 날짜를 입력할 때 시간까지는 입력하지 않기 때문에 내부적으로 LocalDateTime 형식으로 처리하기 위해선 atStartOfDay()나 atTime(LocalTime.MAX)와 같은 처리가 필요하다는 것 또한 알게 되었다.