Dev/Java

Record 로 DTO 생성하기

린네의 2024. 6. 3. 18:05

 

 Record  란?

Java14부터 도입된 클래스로 불변 데이터를 객체 간에 전달하는 작업을 간단하게 만들어주는 역할을 한다.

Record를 사용하면 불필요한 코드를 제거할 수 있고, 적은 코드로도 명확한 의도를 표현할 수 있다.

 

 

  • Record의 특징
  1.  멤버변수는 private final로 선언한다.
  2. 필드별 getter가 자동으로 생성된다.
  3. 모든 멤버변수를 인자로 하는 public 생성자를 자동으로 생성한다.  (@AllAgrsConstructure과 유사하지만 생성자가 실행될 때 인스턴스 필드를 수행할 수 없다.)
  4. equals, hashcode, toString을 자동으로 생성한다.
  5. 기본 생성자는 제공하지 않으므로 필요한 경우 직접 생성해야 한다.

 

 

Record로 바꿔보기

 

  • 변경 전
@Getter
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Builder
public class PromotionDto implements {
    private int id;
    private String promotion_type; //쿠폰 타입 (쿠폰, 코드)
    private String name;
    private String discount_type; // WON : 금액 할인, PERCENT : %할인
    private int discount_value; // 할인 금액 or 할인 %
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate use_started_at; // 쿠폰 사용가능 시작 기간
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private LocalDate use_ended_at; // 쿠폰 사용가능 종료 기간

    public static PromotionDto entityToDto(Promotion promotion) {
        return builder().id(promotion.getId())
                .promotion_type(promotion.getPromotion_type())
                .name(promotion.getName())
                .discount_type(promotion.getDiscount_type())
                .discount_value(promotion.getDiscount_value())
                .use_started_at(promotion.getUse_started_at())
                .use_ended_at(promotion.getUse_ended_at()).build();
    }

}

 

 

  • 변경 후 
@Builder
public record PromotionRecord(
     int id,
     String promotion_type,
     String name,
     String discount_type,
     int discount_value,
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     LocalDate use_started_at,
     @DateTimeFormat(pattern = "yyyy-MM-dd")
     LocalDate use_ended_at) {
    
        public PromotionRecord entityToDto(Promotion promotion) {
            return builder().id(promotion.getId())
                    .promotion_type(promotion.getPromotion_type())
                    .name(promotion.getName())
                    .discount_type(promotion.getDiscount_type())
                    .discount_value(promotion.getDiscount_value())
                    .use_started_at(promotion.getUse_started_at())
                    .use_ended_at(promotion.getUse_ended_at()).build();
        }
}

 

변경 후에 @Getter, @NoArgsConstructor(access = AccessLevel.PROTECTED), @AllArgsConstructor(access =  AccessLevel.PROTECTED)와 같은 애노테이션을 생략할 수 있고, private final을 추가하지 않아도 내부적으로 자동으로 추가되는 것을 알 수 있었다.

 

나는 실제로 DTO생성 시 Record로 사용하고 있는데 편하다 :D. 아직까지 단점을 찾진 못한 것 같다.