Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[spring jpa] AttributeConverter #50

Open
backtony opened this issue Apr 22, 2023 · 0 comments
Open

[spring jpa] AttributeConverter #50

backtony opened this issue Apr 22, 2023 · 0 comments

Comments

@backtony
Copy link
Owner

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을 사용할 수 없다.
  • Money를 한 개의 컬럼에 매핑하기 위한 AttributeConverter 구현체는 아래와 같다.
@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를 자동으로 적용한다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant