@Enumerated 보다 @Convert 사용이 권장되는 이유

영석·2024년 12월 18일
post-thumbnail

📚 Annotation

  • @Enumerated
    Entity필드의 Enum타입을 DB에 매핑할때 사용하는 어노테이션

  • @Convert
    Entity의 필드타입을 변환하여 DB에 저장하거나 DB에서 읽어올때 변환작업
    이 필요할때 사용하는 어노테이션

📚 @Convert 사용이 권장되는 이유?

먼저 @Enumerated 의 속성을 알아야한다.

  1. EnumType.ORDINAL
    Enum타입을 순서에 맞는 숫자로 변환해서 DB에 저장
  2. EnumType.STRING
    Enum타입을 그대로 문자열로 DB에 저장

EnumType.STRING을 사용한다면 @Convert를 사용 할 필요는 없다
하지만 DB에 동일한 문자열을 여러번 저장하는 것은 용량을 많이 필요로 하기때문에 권장하지 않는다.

EnumType.ORDINAL을 사용하여 문자열 -> 숫자로 저장하는것이 효율적일 것이다.
하지만 EnumType.ORDINAL은 프로젝트가 복잡해질때 유지보수관련 문제점이 생긴다


🚨 EnumType.ORDINAL 문제점

public Enum Stat{
	GOOD, FINE, BAD
}

만약 EnumType.ORDINAL으로 변환을 한다면
GOOD = 1, FINE = 2, BAD = 3 으로 DB에 저장될것이다.

하지만 모종의 이유로 위 코드를 수정할때 Enum 필드의 순서가 변경이 된다면 잘못된 값으로 매핑이 될것이다.
이는 큰 규모의 프로젝트에서 그리 효율적이지 못한 방향이다.

Convert 사용을 권장하는 가장 큰 이유다.

📚 @Convert를 사용하자!

  • 예제코드

🌱 Stat.java

public Enum Stat{
	GOOD(1),
	FINE(2),
	BAD(3);

	private Integer code;
	
	Enum(Integer code){
		this.code = code;
	}

	public Integer getCode(){
		return code;
	}

	public static Stat ofLegacyCode(Integer code){
		for(Stat stat : Stat.values()){
			if(code == stat.getCode()){
				return stat;
			}
		}
		throw new IllegalArgumentException("Error!")
	}
}

먼저 Enum Class이다. Enum필드 뒤에 고유 숫자를 부여하고
DB에 저장할때는 getCode()를 사용하여 문자 -> 숫자로 변환하고
DB에서 읽어올때는 ofLegacyCode()를 사용해서 숫자 -> 문자로 변환한다.

🌱 StatConverter.java

@Converter(autoApply = true)
public class StatConverter implements AttributeConverter<Stat, Integer>{
	@Override
	public Integer convertToDatabaseColumn(Stat stat){
		if(!Objects.isNull(stat)){
			return stat.getCode();
		}
		throw new IllgalArgumentException("Error!");
	}

	@Override
	public Stat convertToEntityAttribute(Integer code){
		if(!Objects.isNull(code)){
			return Stat.ofLegacyCode(code);
		}
		throw new IllegalArgumentException("Erorr!!!");
	}
}

AttributeConverter<K,V>의 interface를 상속하여 각 interface에 맞게 재정의 해주면된다.

  • convertToDatabaseColumn
    Enum타입을 숫자로 변환하여 DB에 저장하는 메서드
  • convertToEntityAttribute
    DB에서 읽어온 숫자를 Enum 필드와 매핑하여 반환하는 메서드

🌱 StatEntity.java

	@Column
	@Convert(converter = StatConverter.class)
    private Stat stat;

Entity의 필드에 @Convert를 위 처럼 적용해줘야한다.

profile
느리게 갱신되는 개발실력 - >_0

0개의 댓글