티스토리 뷰

Enum Converter의 도입 필요성

회사의 데이터베이스에서 id와 name만 가지고 있는 DrinkType, CategoryType, PaymentType과 같은 테이블이 약 20개 이상이 존재한다. PHP -> Spring 으로 변환하는 프로젝트에서 우리는 이러한 테이블을 Enum을 사용해서 값을 관리하기로 결정했다.

또한 많은 테이블이 Status라는 컬럼을 가지고 있는데, 이는 0과 1 뿐만 아니라 -1, 2, 3 처럼 여러가지 상태 값을 가지고 있다. 컬럼을 설명하는 엑셀 파일이 존재하지만, 이는 값이 궁금하면 엑셀파일에서 검색해야하는 번거로움을 가지고 있다. 하지만 기존에 존재하는 Status와 같은 값을 모두 String 값으로 변환해 저장하는 것은 추가 작업이라고 생각하여, DB에는 계속 기존 코드값으로 저장하되 0, 1, 2가 무엇을 나타내는 값인지 잘 알아볼 수 있는 방법은 없을까? 라고 고민하던 차에 java에서의 상태값을 Enum으로 변경해서 매핑할 수 있는 방법을 찾게 되었다.

이는 Converter를 사용하여 Enum을 관리하는 방법인데, 이 방법을 도입하게 되면 Status 칼럼이 어떤 의미를 갖고 있는지 번거롭게 찾지 않아도 될 것이며, id와 name만 가지고 있는 테이블들을 좀더 수월하고 효과적으로 관리할 수 있게 될 것이다.

Enum Converter 사용 방법

1. Enum 생성

@Getter
public enum Size {
    SHORT(237, "SHORT", 1L),
    TALL(355, "TALL", 2L),
    GRANDE(473, "GRANDE",3L),
    VENTI(591, "VENTI",4L);

    private final int sizeVolume;
    private final String size;
    private final Long code;

    Size(int sizeVolume, String size, Long code) {
        this.sizeVolume = sizeVolume;
        this.size = size;
        this.code = code;
    }

    public static Size ofCode(Long dbData) {
        return Arrays.stream(Size.values())
                .filter(v -> v.getCode().equals(dbData))
                .findAny()
                .orElseThrow(() -> new IllegalArgumentException("존재하지 않는 음료 사이즈 코드입니다."));
    }
}

Enum에서 ofCode 메서드를 통해, db에서 데이터를 읽어 JPA entity로 매핑할 때 Enum과 db 테이블 값이 자동으로 컨버팅된다. 상태 코드 값이 존재하지 않으면 에러를 띄우는 부분을 작성해준다.

2. Converter 코드 작성

@Converter
public class SizeConverter implements AttributeConverter<Size, Long> {

    @Override
    public Long convertToDatabaseColumn(Size size) {
        return size.getCode();
    }

    @Override
    public Size convertToEntityAttribute(Long dbData) {
        return Size.ofCode(dbData);
    }
}
  • @Convert 어노테이션을 선언해준다
  • AttributeConverter<X, Y>를 implements 해준다
  • convertToDatabaseColumn() (Enum -> DB 데이터) / convertToEntityAttribute() (DB데이터 -> Enum) 를 오버라이딩 해준다.

★ 주의 ★
AttributeConverter<X, Y> 의
X는 Entity Attribute
Y는 Database Column이며, Y에는 기본 타입(int, double)이 사용 불가능 하다.

3. Entity에 Enum 필드 추가.

@Entity
@Getter
@RequiredArgsConstructor
public class Beverage {
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Id
    private Long id;

    @Column
    private String beverage;

    @Convert(converter = SizeConverter.class)
    private Size size;

    @OneToMany(mappedBy = "beverage")
    @JsonManagedReference(value = "beverage-fk")
    private List<BeverageIngredient> beverageIngredients;

    public Beverage(String beverage, Long sizeCode) {
        this.beverage = beverage;
        this.size = Size.ofCode(sizeCode);
    }
}

확장성 고려 필요

 위의 도입 필요성 부분에서 언급했다시피 이러한 Enum들이 20개가 넘어갈 텐데, Enum에서는 OfCode부분과 Converter 선언 부분의 convertToDatabaseColumn(), convertToEntityAttribute() 메서드가 반복되는 것을 볼 수 있다. EnumConverter에서 implements 하는 AttributeConverter를 커스터마이징 하는 방법으로 코드를 줄일 수 있지만, 아직 구현을 해보지 않은 터라 참고했던 자료를 첨부하는 걸로 마친다.

 

https://techblog.woowahan.com/2600/

 

Legacy DB의 JPA Entity Mapping (Enum Converter 편) | 우아한형제들 기술블로그

{{item.name}} 안녕하세요. 저는 우아한형제들 비즈상품개발팀의 이은경입니다. Legacy DB의 JPA Entity Mapping (복합키 매핑 편)에 이어 저는 DB의 코드값과 Java Enum을 연결해주는 과정에서 유용하게 사용

techblog.woowahan.com

 

댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함