어떤 값을 저장할 때 데이터베이스에 저장할 때 원하는 값으로 저장하고 조회할 때도 원하는 값이나 타입으로 반환할 때 사용합니다.
예를 들어 개인정보의 암호화하여 저장해야하거나 Boolen 타입일 때 Y, N 값으로 데이터베이스에 저장하는 등 다양한 경우에 사용될 수 있습니다.
AttributeConverter란
AttributeConverter 클래스는 프로퍼티의 값을 저장하거나 읽을 때 사용할 수 있는 인터페이스입니다.
public interface AttributeConverter<X, Y> {
// 엔티티의 데이터를 데이터베이스 컬럼에 저장할 데이터로 변환한다.
Y convertToDatabaseColumn(X attribute);
// 데이터베이스에서 조회한 컬럼 데이터를 엔티티 데이터로 변환한다.
X convertToEntityAttribute(Y dbData);
}
사용예제
암호화 및 복호화할 때 사용하는 케이스에 대해서 설명하겠습니다.
import jakarta.persistence.AttributeConverter;
public class CryptoConverter implements AttributeConverter<String, String> {
@Override
public String convertToDatabaseColumn(String text) {
// 데이터베이스 저장할 때 호출됩니다.
return Crypto.encrypt(text);
}
@Override
public String convertToEntityAttribute(String text) {
// 데이터베이스에서 조회할 때 호출됩니다.
return Crypto.decrypt(text);
}
}
Converter는 따로 스프링빈에 등록하지 않아도 사용가능합니다.
해당 Converter를 적용하고 싶은 엔티티의 프로퍼티에 @Convert 어노테이션을 추가해주시면 적용가능합니다.
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "email")
private String email;
@Column(name = "name")
private String name;
@Column(name = "phone")
@Convert(converter = CryptoConverter.class)
private String phone;
@Column(name = "role")
private String role;
}
@Convert 어노테이션을 클래스 레벨에도 설정 가능합니다.
이때는 attributeName 속성을 사용하여 어떤 프로퍼티에 적용할지 명시해주셔야합니다.
@Entity
@Convert(converter = CryptoConverter.class, attributeName = "phone")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "email")
private String email;
@Column(name = "name")
private String name;
@Column(name = "phone")
private String phone;
@Column(name = "role")
private String role;
}
글로벌 설정
@Converter(autoApply = true)로 글로벌 설정이 가능하고 @Convert로 프로퍼티에 사용하지 않더라도 적용됩니다.
AttributeConverter<X, Y>일 때 모든 X타입에 대해서 Converter가 적용됩니다.
import jakarta.persistence.AttributeConverter;
@Converter(autoApply = true)
public class CryptoConverter implements AttributeConverter<String, String> {
@Override
public String convertToDatabaseColumn(String text) {
// 데이터베이스 저장할 때 호출됩니다.
return Crypto.encrypt(text);
}
@Override
public String convertToEntityAttribute(String text) {
// 데이터베이스에서 조회할 때 호출됩니다.
return Crypto.decrypt(text);
}
}
주의사항
- Converter를 구현하실 때 저장및 조회하는 엔티티마다 호출하기 때문에 복잡한 로직이나 외부시스템에 연동할 경우 속도 이슈가 발생할 수 있습니다.
- convertToDatabaseColumn과 convertToEntityAttribute 함수를 구현하실 때 null 값에 대한 처리를 해주셔야 잘못된 값이 적용되거나 에러가 발생하지 않습니다.
- autoApply = true는 Enum을 변경하는 케이스나 전체적인 엔티티를 수정하는 경우에만 사용해야합니다.
'DB' 카테고리의 다른 글
| JPA Converter처럼, MyBatis TypeHandler로 변환 책임 한 곳에 모으기 (0) | 2025.09.02 |
|---|---|
| CaseBuilder 대신 BooleanBuilder를 써야 했던 이유(Feat: querydsl) (2) | 2025.07.27 |
| Querydsl 다중 where 조건 만들기 (1) | 2025.04.23 |
| EXISTS 연산자에 대해서(Feat: querydsl) (1) | 2025.04.13 |
| ORA-01502: 인덱스 인덱스 이름 또는 인덱스 분할영역은 사용할 수 없는 상태입니다. (0) | 2025.02.18 |