새소식

Database

JPA - AttributeConverter

  • -

AttributeConverter

AttributeConverter는 주로 다음과 같은 상황에서 사용됩니다.

  • JPA가 지원하지 않는 타입을 매핑
  • 두 개 이상의 속성을 갖는 밸류 타입을 한 개 칼럼에 매핑

 

JPA가 지원하지 않는 타입을 매핑

public interface AttributeConverter<X,Y> {
    public Y convertToDatabaseColumn (X attribute);
    public X convertToEntityAttribute (Y dbData);
}
  • X : 엔티티의 속성에 대응하는 타입
  • Y : DB에 대응하는 타입
  • convertToDatabaseColumn
    • 엔티티의 X 타입 속성을 Y 타입의 DB 데이터로 변환합니다.
    • 엔티티 속성을 DB에 반영할 때 사용됩니다.
  • convertToEntityAttribute
    • Y 타입으로 읽은 DB 데이터를 엔티티의 X 타입의 속성으로 변환합니다.
    • 엔티티 조회시 DB에서 읽어온 데이터를 엔티티의 속성에 반영할 떄 사용됩니다.

 

public enum DirectoryType {
    DEFAULT, CUSTOM, UNKNOWN
}

@Converter
public class DirectoryTypeConverter implements AttributeConverter<DirectoryType, String> {
    @Override
    public String convertToDatabaseColumn(DirectoryType attribute) {
        return attribute.name();
    }

    @Override
    public DirectoryType convertToEntityAttribute(String dbData) {
        return Arrays.stream(DirectoryType.values()).filter(constraintSet -> constraintSet.name().equals(dbData))
            .findAny().orElse(DirectoryType.UNKNOWN);
    }
}

@Entity
public class ServiceDirectory {
    @Id
    @Column
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long no;


    @Convert(converter = DirectoryTypeConverter.class)
    private DirectoryType directoryType;
}

 

두 개 이상의 속성을 갖는 밸류 타입을 한 개 컬럼에 매핑

이런 경우는 흔치 않지만 이렇게 할 수 있다 정도로만 알아두면 될 것 같습니다.

public class Money {
    private Double value;
    private String currency;

    public Money(Double value, String currency) {
        this.value = value;
        this.currency = currency;
    }

    public Double getValue() {
        return value;
    }

    public void setValue(Double value) {
        this.value = value;
    }

    public String getCurrency() {
        return currency;
    }

    public void setCurrency(String currency) {
        this.currency = currency;
    }

    @Override
    public String toString() {
        return value.toString() + currency;
    }
}

 

  • Money 타입을 DB에 보관할 때 “1000KRW”이나 “100USD”와 같은 문자열로 저장다고 가정합니다.
  • Money를 한 개의 칼럼에 매핑하므로 @Embeddable을 사용할 수 없습니다.

 

@Converter(autoApply = true)
public class MoneyConverter implements AttributeConverter<Money, String> {

    @Override
    public String convertToDatabaseColumn(Money attribute) {
        if (attribute == null) {
            return null;
        }
        return attribute.toString();
    }

    @Override
    public Money convertToEntityAttribute(String dbData) {
        if (dbData == null) {
            return null;
        } else {
            String value = dbData.substring(0, dbData.length() - 3);
            String currency = dbData.substring(dbData.length() - 3);
            return new Money(Double.valueOf(value), currency);
        }
    }
}

 

autuApply 설정을 true로 설정했으므로 JPA 프로바이더는 MoneyConverter를 자동으로 적용합니다.

'Database' 카테고리의 다른 글

MySQL 8.0 쿼리와 인덱스 처리 방식  (0) 2024.01.01
MySQL 실행계획 보는 방법  (0) 2023.12.31
MySQL 인덱스  (0) 2023.12.30
MySQL 아키텍처  (0) 2023.12.30
Spring Data JPA - QueryDSL 사용하기  (0) 2023.12.30
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감/반응 부탁드립니다.