본문 바로가기
JAVA/JPA

[Java / Spring / JPA] DB 컬럼에 List 데이터 추가하기

by nam_ji 2024. 5. 23.

DB 컬럼에 List 데이터 저장하기

List 데이터 DB 저장 [MySQL]

  • 사이드 프로젝트를 진행하면서 요청된 데이터를 분리하여 여러 개의 데이터가 저장되도록 하는 요구사항이 있었습니다.
  • 여기서 응답을 List 형태로 반환하게 되어 있어 분리된 데이터를 각각 저장하는 방법과 List 그대로 저장하는 방법이 있지 않을까 생각하게 되었습니다.
  • DB는 List 형태의 데이터를 저장하지 못하기 때문에 방법을 찾아보게 되었고, 그 방법으로 저장하려는 List 데이터를 문자열로 변환하여 DB에 저장하고 응답 시 문자열 Json 형태로 변환해서 응답하도록 하는 방법을 찾게 되었습니다.

해결 방법

String 타입으로 변환

  • 엔티티 구조
  • 더보기
    더보기
    package com.namji.datacollection.entity;
    
    import com.fasterxml.jackson.annotation.JsonFormat;
    import jakarta.persistence.*;
    import java.time.LocalDate;
    import java.time.LocalDateTime;
    import java.util.List;
    import lombok.AllArgsConstructor;
    import lombok.Getter;
    import lombok.NoArgsConstructor;
    
    @Entity
    @Getter
    @NoArgsConstructor
    @AllArgsConstructor
    @Table(name = "datas")
    public class Data extends TimeStamp {
    
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Long dataId;
    
      @Column(nullable = false)
      @Convert(converter = StringListConvert.class)
      private List<String> dataInfo;
    
      @Column(nullable = false)
      private LocalDateTime recordedAt;
    
      @ManyToOne(fetch = FetchType.LAZY)
      @JoinColumn(name = "device_id", nullable = false)
      private Device device;
    
      public Data(String info, LocalDateTime recordedAt, Device device) {
        this.dataInfo = info;
        this.recordedAt = recordedAt;
        this.device = device;
      }
    }
 
  • 엔티티를 보면 List<String> dataInfo가 연관관계 없는 단순 필드지만 List로 되어 있습니다.
  • 그 필드에 설정된 @Convert 어노테이션을 통해 List로된 데이터를 문자열로 바꿀 수 있게 해줍니다.
  • 여기서 단순하게 @Convert만 추가해 주면 되는 것이 아니라 StringListConvert처럼 변환을 도와줄 클래스가 필요합니다.
  • StringListConvert
    더보기
    더보기
    package com.namji.datacollection.util.converter;
    
    import com.fasterxml.jackson.core.JsonProcessingException;
    import com.fasterxml.jackson.core.type.TypeReference;
    import com.fasterxml.jackson.databind.ObjectMapper;
    import jakarta.persistence.AttributeConverter;
    import jakarta.persistence.Converter;
    import java.util.List;
    
    @Converter
    public class StringListConvert implements AttributeConverter<List<String>, String> {
    
      private final ObjectMapper objectMapper = new ObjectMapper();
    
      @Override
      public String convertToDatabaseColumn(List<String> dataInfo) {
        try {
          return objectMapper.writeValueAsString(dataInfo);
        } catch (JsonProcessingException e) {
          throw new RuntimeException(e.getMessage());
        }
      }
    
      @Override
      public List<String> convertToEntityAttribute(String data) {
        try {
          return objectMapper.readValue(data, new TypeReference<>() {});
        } catch (JsonProcessingException e) {
          throw new RuntimeException(e.getMessage());
        }
      }
    }
    • convertToDatabaseColumn : Entity 속성 값을 DB에 저장하기 전 변경 동작을 구현하는 메서드입니다.
    • convertToEntityAttribute : DB에서 읽어온 데이터를 Entity의 속성에 입력하기 전 병경 동작을 구현하는 메서드입니다.
    • 지금 프로젝트에서는 String 타입으로 데이터를 받고 저장하기 때문에 String으로 해뒀습니다.