@Enumerated
Entity필드의 Enum타입을 DB에 매핑할때 사용하는 어노테이션
@Convert
Entity의 필드타입을 변환하여 DB에 저장하거나 DB에서 읽어올때 변환작업
이 필요할때 사용하는 어노테이션
먼저 @Enumerated 의 속성을 알아야한다.
- EnumType.ORDINAL
Enum타입을 순서에 맞는 숫자로 변환해서 DB에 저장- EnumType.STRING
Enum타입을 그대로 문자열로 DB에 저장
EnumType.STRING을 사용한다면 @Convert를 사용 할 필요는 없다
하지만 DB에 동일한 문자열을 여러번 저장하는 것은 용량을 많이 필요로 하기때문에 권장하지 않는다.
즉 EnumType.ORDINAL을 사용하여 문자열 -> 숫자로 저장하는것이 효율적일 것이다.
하지만 EnumType.ORDINAL은 프로젝트가 복잡해질때 유지보수관련 문제점이 생긴다
public Enum Stat{
GOOD, FINE, BAD
}
만약 EnumType.ORDINAL으로 변환을 한다면
GOOD = 1, FINE = 2, BAD = 3 으로 DB에 저장될것이다.
하지만 모종의 이유로 위 코드를 수정할때 Enum 필드의 순서가 변경이 된다면 잘못된 값으로 매핑이 될것이다.
이는 큰 규모의 프로젝트에서 그리 효율적이지 못한 방향이다.
Convert 사용을 권장하는 가장 큰 이유다.
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()를 사용해서 숫자 -> 문자로 변환한다.
@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에 맞게 재정의 해주면된다.
@Column
@Convert(converter = StatConverter.class)
private Stat stat;
Entity의 필드에 @Convert를 위 처럼 적용해줘야한다.