전체 일정 조회 API와 선택 일정 조회 API를 구현할 때, queryForObject
와 query
의 차이를 명확히 이해하지 못해 혼란이 있었다. 두 메서드는 비슷해 보이지만 반환하는 결과가 다르기 때문에 상황에 맞는 사용이 중요하다.
전체 일정 조회에서는 여러 개의 일정이 반환되므로 query
를 사용해야 하지만, 선택 일정 조회에서도 query
를 사용하다 보니 단일 결과를 제대로 처리하지 못했다. 결과적으로 선택 일정 조회 시, 결과가 부정확하게 나왔다.
전체 일정 조회의 경우 query
를 사용해 다중 행을 리스트로 반환하고, 선택 일정 조회에서는 queryForObject
를 사용해 단일 행을 반환하는 것으로 문제를 해결했다.
// 선택 일정 조회 - queryForObject 사용
public ScheduleResponseDto getSchedule(@PathVariable Long id) {
String sql = "SELECT * FROM schedules WHERE id = ?";
return jdbcTemplate.queryForObject(sql, (rs, rowNum) -> new ScheduleResponseDto(
rs.getLong("id"),
rs.getString("userName"),
rs.getString("updateDate"),
rs.getString("contents")
), id);
}
query
와 queryForObject
는 결과가 여러 개일 때와 하나일 때 명확히 구분해서 사용해야 한다. 특히, 단일 행을 처리할 때는 queryForObject
를 사용하는 것이 올바른 선택이다.
초기 API 설계에서 updateDate
필드를 String
타입으로 처리했지만, 날짜와 시간을 LocalDateTime
으로 다루고자 했다. 하지만 API 요청과 응답에서 날짜 타입 변환 과정에서 문제에 직면했다.
ResultSet
에서 updateDate
값을 String
으로 가져와서 LocalDateTime
으로 변환하는 과정에서 타입 불일치 오류가 발생했다.엔티티(Schedule)에서 updateDate
를 LocalDateTime
으로 유지하면서, DTO에서 LocalDateTime
을 String
으로 변환하여 클라이언트에 전달하는 방법을 선택했다. ScheduleResponseDto
에서 DateTimeFormatter
를 사용해 LocalDateTime
을 ISO 8601 형식으로 변환해 전달했다.
public class ScheduleResponseDto {
private Long id;
private String userName;
private String updateDate;
private String contents;
public ScheduleResponseDto(Schedule schedule) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
this.updateDate = schedule.getUpdateDate().format(formatter); // LocalDateTime을 String으로 변환
this.id = schedule.getId();
this.userName = schedule.getUserName();
this.contents = schedule.getContents();
}
}
LocalDateTime을 API에서 직접 사용하지 않고 String
으로 변환하여 처리하는 것이 더 실용적임을 알게 되었다. 클라이언트와 서버 간에 날짜 형식이 일치하지 않으면 오류가 발생할 수 있기 때문에, 이와 같은 변환 과정이 필요하다.
이번 트러블슈팅을 통해 날짜 처리 방식(LocalDateTime)과 쿼리 메서드(query
, queryForObject
)의 차이를 확실하게 이해할 수 있었다. 앞으로 API 설계 시, 이 부분을 더 신경 써야 할 필요성을 느꼈다.