[SpringBoot] Date 대신 LocalDateTime 을 사용하자.

울상냥·2023년 2월 7일
0

SpringBoot

목록 보기
2/11
post-custom-banner

프로젝트 진행중 별 생각없이 Date를 사용해서 개발하고 있었다. 그러고 보니 지난번 프로젝트에서는 LocalDateTime을 사용했었는데 무엇이 다른가 해서 알아봤다

자세한 설명은 이 글에서 읽을 수 있다.
(한국사도 어려웠는데 자바 시간라이브러리의 역사마저 어렵다)
대충 요약하자면

  • 불변 객체가 아니다( not immutable)
  • int 상수 필드의 남용
  • 헷갈리는 월 지정
  • 일관성 없는 요일 상수
  • Date와 Calendar의 불편한 역할 분담
  • 오류에 둔감한 시간대 ID지정
  • java.util.Date 하위 클래스의 문제

등의 문제로 java8에서는 LocalDateTime, LocalDate, LocalTime을 제공한다고 한다.
결론은 LocalDateTime을 사용해라...!

그래서 Date -> LocalDateTime 으로 리팩토링을 했다.


Entity

Date 사용

날짜와 시간정보를 따로 사용하기 위해서 LocalDateLocalTime을 사용하였다.
기존에는 Date를 매핑하기 위해서 entity클래스에 @Temporal(TemporalType.DATE)@Temporal(TemporalType.TIME) 을 사용하였다.

@Getter
@NoArgsConstructor
@Entity
public class Hours {

    ... (중략)
    
    @Temporal(TemporalType.TIME)
    private Date time;
    
    @Temporal(TemporalType.DATE)
    private Date date;
    
}

LocalTime 적용

위에서 사용한 @TemporalDateCalendar에만 사용할 수 있는 어노테이션이다.
jpa2.2 버전부터는 LocalDateTime을 알아서 매핑해준다.

@Getter
@NoArgsConstructor
@Entity
public class Hours {

    ... (중략)
    
    private LocalTime time;
    
    private LocalDate date;
    
}

Dto

Json과 Date의 변환을 위해서 @JsonFormat 어노테이션을 사용하여 형식, 타임존 등을 지역적으로 설정할 수 있다.
전역 설정을 위해서 설정파일에 적용시킬 수 있으나 Date에만 지원을 한다고 한다. LocalDateTime을 전역 설정하기 위해서는 Jackson의 기본Deserializer 을 커스텀하여 사용할 수 있다.
현재는 필드마다 어노테이션을 붙여 사용하고있지만 사용하는 필드가 많아지게되면 커스텀Deserializer을 작성하는게 유용할 것 같다.

Date 사용

Date의 경우 timezone의 영향을 받아 @JsonFormat에 timezone을 지정해주지 않으면 원치 않는 시간이 db에 저장되는 불상사를 겪을 수 있다.

Request

@Getter
public class HoursRequestDto {

	... (중략)

    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Seoul")
    private Date date;

    @JsonFormat(pattern = "HH:mm", timezone = "Asia/Seoul")
    private Date time;
}

Response

@Getter
public class HoursResponse {

	... (중략)

    @JsonFormat(pattern = "yyyy-MM-dd", timezone = "Asia/Seoul")
    private Date date;
    
    @JsonSerialize(as = date.class)
    @JsonFormat(pattern = "HH:mm", timezone = "Asia/Seoul")
    private Date time;
}

time의 경우 db에 HH:mm:ss 형태로 저장되는데 어째서인지 응답에서 @JsonFormat이 적용되지 않고 HH:mm:ss형태로 json응답을 보냈다.
@JsonSerialize(as = date.class)을 함께 사용해주었더니 문제는 해결되었다.

LocalTime 적용

LocalDateTime 에서는 timezone을 사용하지 않는다.

Request

@Getter
public class HoursRequestDto {

	... (중략)

    @JsonFormat(pattern = "yyyy-MM-dd")
    private Date date;

    @JsonFormat(pattern = "HH:mm")
    private Date time;
}

Response

@Getter
public class HoursResponse {

	... (중략)

    @JsonFormat(pattern = "yyyy-MM-dd")
    private LocalDate date;
    
    @JsonFormat(pattern = "HH:mm")
    private LocalTime time;
}

LocalTime의 경우에도 db에 HH:mm:ss 형태로 저장된다.

@JsonFormat(pattern = "HH:mm") 의 적용으로 HH:mm 형태로 json응답을 한다.

profile
안되면 되게하라
post-custom-banner

0개의 댓글