가독성 좋은 데이터베이스를 위한 Converter 적용

LTT·2024년 11월 17일

Introduce


사이드 프로젝트의 데이터베이스와 백엔드 개발을 위해 Converter 를 사용해보려고 한다.

위와 같이 가독성있게 boolean형식의 데이터베이스를 유지하고,

List형이나 JSON형식을 쉽게 읽고쓰기 위한 Converter를 구현해보도록 하자. JSON Converter 는 아직 필요가 없다 판단하여, 필요할 경우 구현해보도록 하겠다.

@Converter 작성


BooleanConverter

@Converter
@RequiredArgsConstructor
public class BooleanConverter implements AttributeConverter<boolean, String> {
    @Override
    public String convertToDatabaseColumn(boolean attribute) {
        return attribute ? "Y" : "N";

    }

    @Override
    public boolean convertToEntityAttribute(String dbData) {
        return "Y".equals(dbData);
    }
}

우선 BooleanConverter부터 살펴봐보자.

convertToDatabaseColumn

	 	@Override
    public String convertToDatabaseColumn(boolean attribute) {
        return attribute ? "Y" : "N";

    }

Boolean타입의 값을 받아 true이면 “Y”를 저장하고, false이면 “N”을 저장하여

DB에 이런 형식으로 저장하게 하는 메소드이다. ConvertToDatabaseColumn은 데이터베이스에 write 작업을 수행할 때 실행되는 메소드이다.

convertToEntityAttribute

	  @Override
    public boolean convertToEntityAttribute(String dbData) {
        return "Y".equals(dbData);
    }

Database의 데이터 타입이 char(1)로 되어있기에 String으로 선언하여, “Y”면 true를, “N”이면 false를 반환하는 간단한 Converter이다.

StringListConverter

@Converter
@RequiredArgsConstructor
public class StringListConverter implements AttributeConverter<List<String>, String> {
    private final ObjectMapper objectMapper =
            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 objectMapper.writeValueAsString(attribute);
        } catch (JsonProcessingException e) {
            throw new IllegalArgumentException();
        }
    }

    @Override
    public List<String> convertToEntityAttribute(String dbData) {
        TypeReference<List<String>> listType = new TypeReference<>() {};
        try {
            return objectMapper.readValue(dbData, listType);
        } catch (IOException e) {
            throw new IllegalArgumentException();
        }
    }
}

Converter는 별도의 테이블로 분리하기에는 굳이, 혹은 그정도의 소요는 필요 없을 것 같을 때 사용할 Converter이다.

["test1","test2","test3","test4"]

위와 같은 List<String> 을 하나의 text 타입으로 저장하기 위한 Converter이다.

용도

이런 물품을 커뮤니티에 올리고 이미지들을 올려야 하는데, 이 이미지들만 별도의 테이블로 분리하기엔 매번 호출하기에도 불편하고, 소요가 크다고 판단하여 다음과 같은 Converter를 사용하려고 한다.

Entity에 적용


@Entity
@Table(name = "users")
@Getter @Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserJpaEntity extends BaseTime {
		// ...
    // 다른 컬럼들
    // ...
    @Convert(converter = BooleanConverter.class)
    @Column(name = "dm_alarm", nullable = false)
    private boolean dmAlarm = true;
    @Convert(converter = BooleanConverter.class)
    @Column(name = "like_alarm", nullable = false)
    private boolean likeAlarm = true;
    @Convert(converter = BooleanConverter.class)
    @Column(name = "notification_alarm", nullable = false)
    private boolean notificationAlarm = true;
    @Convert(converter = BooleanConverter.class)
    @Column(name = "withdraw_status", nullable = false)
    private boolean withdrawStatus = false;
    @Column(name = "withdraw_at")
    private OffsetDateTime withdrawAt;
}

위와 같이 @Convert(converter = BooleanConverter.class)를 위에 Annotation으로 정의하여 사용할 수 있다.

형식은 nullable = false로 지정해두었기 때문에, boolean 을 사용했다.

이렇게 Converter를 사용하여 조금 더 가독성있는 Database를 유지할 수 있다.

profile
개발자에서 엔지니어로, 엔지니어에서 리더로

0개의 댓글