설문조사 프로젝트를 개발하면서 엔티티를 구현하고 있는데 하나의 컬럼에 여러 가지 설문 평가 요소들을 넣기 위하여 converter가 필요해 만들게 되었다.
Survey
@Column(columnDefinition = "mediumText COMMENT '추가 기본 정보 수집'")
@Convert(converter = StringConverter.class)
private List<String> custom;
@Column(columnDefinition = "mediumText COMMENT '평가 요소'")
@Convert(converter = ElementConverter.class)
private List<SurveyRequest> elements;
StringConverter를 사용한 custom 컬럼에는 평가 요소로 미리 등록되어 있는 요소들 외에 추가적으로 수집하고자 하는 내용들을 넣을 것이다.
ElementConverter를 사용한 elements 컬럼에는 enum에 미리 넣어둔 평가 요소들을 저장할 수 있도록 할 것이다.
StringConverter
@Converter
public class StringConverter implements AttributeConverter<List<String>, String> {
private static final ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
@Override
public String convertToDatabaseColumn(List<String> attribute) {
try {
return mapper.writeValueAsString(attribute);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException(e);
}
}
@Override
public List<String> convertToEntityAttribute(String dbData) {
try {
return mapper.readValue(dbData, new TypeReference<List<String>>() {});
} catch (IOException e) {
throw new IllegalArgumentException(e);
}
}
}
StringConverter의 역할
1. 목적
- List<String> 데이터를 데이터베이스에 저장 가능한 JSON 문자열로 변환하고, 이를 다시 List<String> 객체로 변환하는 역할을 한다.
2. 주요 기능
- convertToDatabaseColumn
: 엔티티의 필드 데이터(List<String>)를 데이터베이스의 컬럼(JSON 문자열) 형태로 직렬화한다.
- convertToEntityAttribute
: 데이터베이스에서 가져온 JSON 문자열 데이터를 엔티티의 필드 데이터(List<String>)로 역직렬화한다.
3. 사용 사례
- JSON 데이터를 문자열로 저장할 수 있는 데이터베이스 컬럼(ex. TEXT, VARCHAR)에 리스트 형태의 문자열 데이터를 저장하거나 불러오는 데 사용된다.
- ex) ["value1", "value2", "value"]
ElementConverter
@Converter
public class ElementConverter implements AttributeConverter<List<SurveyRequest>, String> {
private final ObjectMapper mapper = new ObjectMapper()
.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
.configure(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES, false);
@Override
public String convertToDatabaseColumn(List<SurveyRequest> attribute) {
try {
return mapper.writeValueAsString(attribute);
} catch (JsonProcessingException e) {
throw new IllegalArgumentException(e);
}
}
@Override
public List<SurveyRequest> convertToEntityAttribute(String dbData) {
TypeReference<List<SurveyRequest>> typeReference = new TypeReference<List<SurveyRequest>>() {};
try {
return mapper.readValue(dbData, typeReference);
} catch (JsonProcessingException e) {
throw new RuntimeException(e);
}
}
}
ElementConverter의 역할
1. 목적
- List<SurveyRequest> 데이터를 데이터베이스에 저장 가능한 JSON 문자열로 변환하고, 이를 다시 List<SurveyRequest> 객체로 변환하는 역할을 한다.
2. 주요 기능
위 StringConverter와 동일하다.
3. 사용 사례
- 엔터티에서 복잡한 데이터 구조(SurveyRequest 객체 리스트)를 JSON 문자열로 저장하거나 불러오는 데 사용된다.
- SurveyRequest는 엔터티가 아니며, 데이터베이스에 바로 저장할 수 없는 객체이기 때문에 JSON 형식으로 변환하여 데이터베이스에 저장한다.
- ex) [ {"id": 1, "name: "Survey1", "completed": false}, {"id": 2, "name: "Survey2", "completed": true} ]
공통된 역할
1. JSON 직렬화/역직렬화
- 두 컨버터 모두 Jackson 라이브러리를 사용하여 객체 -> JSON 문자열 및 JSON 문자열 -> 객체 변환을 수행한다.
2. JPA와 데이터베이스 간 타입 변환
- JPA는 기본적으로 엔티티와 데이터베이스 간 매핑을 지원하지만, 복잡한 데이터 구조(ex. 리스트, 객체리스트)를 직접 처리하지 못한다.
- 이 컨버터를 사용하면 JSON 문자열을 활용해 복잡한 구조를 데이터베이스에 저장하고, 이를 다시 객체로 변환하여 사용할 수 있다.
3. 유연한 데이터 처리
- 복잡한 데이터 구조를 유지하면서, 데이터베이스에서 쉽게 조회 및 업데이트를 할 수 있다.
다음에는 코틀린으로 이 코드를 구현해보도록 해야겠다.
'개발' 카테고리의 다른 글
[개발] Survey 엔티티 생성 및 Converter 설정하기 - Kotlin (1) | 2024.11.20 |
---|---|
Kotlin에 Querydsl 적용하기 - 24.11.14 기준 (0) | 2024.11.14 |
[개발] IntelliJ와 GitHub 연결하기 (1) | 2024.10.21 |
[개발] 사이드 프로젝트 시작 (1) | 2024.10.10 |
[에러] swagger로 테스트 시 LocalDateTime typeMisMatch (0) | 2024.06.26 |