SpringBoot 엔티티에 Map<String,List<String>>타입 저장하기

Juice🌱·2024년 1월 18일
1

SpringBoot

목록 보기
4/7

이번 velog에서는 SpringBoot로 DB에 Map<String,List<String>>저장하는 방법에 대해 알아볼게요

Map

여러 데이타들 저장할 때, 순차적으로 저장하는게 아니라 keyvalue로 저장을 하는데. key라는 이름을 가지고 그에 해당하는 value를 저장합니다. -> key는 중복이 불가능합니다.

Entity 설정 - Project.java

	@ElementCollection
    @CollectionTable(name = "TOOL", joinColumns = @JoinColumn(name = "PROJECT_ID"))
    @MapKeyColumn(name = "tool_id")
    private Map<String,Tool> tool;

기본적으로 SpringBoot는 HashMap은 지원해주지만, Map<String,List<String>>과 같은 타입을 저장하는것은 지원해주지 않습니다. 그래서 저희가 따로 Tool이라는 List<Sring>타입 변수를 만들고 Map<String,Tool>로 선언해서 HashMap과 같은 타입으로 변환해줘야 합니다.

ElementCollection

@OneToMany혹은 @ManyToOne처럼 collection을 엔티티로 사용하는 것이 아니라. String이나 Embedded처럼 Type을 컬렉션으로 사용하고 싶을 때 쓰는 어노테이션입니다.

🤔 : 왜??

🧐 : Mysql과 같은 관계형 DB(Relation DB)에서는 Collection을 담을 수 있는 구조가 없어서 따로 테이블을 만들어 저장해야 합니다. ElementCollection은 해당 필드가 컬렉션 객체임을 JPA에게 알려주고, Embeddable Class를 생성하고 @OneToMany 관계를 만들어줍니다. 그리고 @ElementCollection@CollectionTable과 같이 사용됩니다.

CollectionTable

매핑할 테이블에 관한 정보를 지정하는 어노테이션입니다. 만약 생략한다면 디폴트값인 {엔티티이름}_{컬렉션 필드 이름}을 이용해서 매핑합니다.

MapKeyColumn

이는 Embedd할 Tool과 관련이 있어서 Tool.java를 설명하면서 같이 설명하겠습니다.

Entity설정 - Tool.java

아래는 List<String>타입 변수를 다른 embeddable entity로 만든 코드입니다.

@Embeddable //이 엔티티가 다른 값type에 내장(embedded)될 수 있는 타입이다!
@NoArgsConstructor
@AllArgsConstructor
@Getter
public class Tool {
   @Convert(converter = ListStringConverter.class)
   private List<String> tool;
}

Map형식은 Keyvalue로 이뤄진다고 했습니다. Project.java에서 사용하는 @MapKeyColumnString으로 된 Key Column을 만들고 이를 key로 사용한다는 뜻입니다. 이와 비슷한 @MapKey가 있지만, 이 어노테이션 사용하려면 Tool.java에서 tool_id 필드를 생성해줘야 합니다.

@Converter 와 @Convert

Tool.java에 있는 Conver 어노테이션이 보이실겁니다. 이거는 프런트엔드에서 받을 List<String>을 DB에 문자열로 저장하고, 프런트엔드에서 호출하면 DB에 저장한 문자열을 다시 보내줘야 하기 때문에 만들어야 합니다.

@Converter
public class ListStringConverter implements AttributeConverter<List<String>, String>{
    @Override
    public String convertToDatabaseColumn(List<String> attribute) {
        if (attribute == null || attribute.isEmpty()) {
            return null; // 또는 적절한 기본값 반환
        }
        return String.join(",", attribute);
    }

    @Override
    public List<String> convertToEntityAttribute(String dbData) {
        if (dbData == null || dbData.trim().isEmpty()) {
            return new ArrayList<>();
        }
        return Arrays.asList(dbData.split(","));
    }
}
  • convertToDatabaseColumn -> 프런트엔드에서 넘어온 List를 문자열로 바꾸고 DB에 저장하기
  • convertToEntityAttribute -> "," 기준으로 문자열 나눠서 List에 넣기
"tool": {
        "개발": ["springboot", "git"],
        "디자인": ["피그마", "피그잼"]
    }

이렇게 프런트엔드에서 준다면

이렇게 DB에 저장됩니다.

이렇게 해서 Map<String,List<String>>을 받아서 DB에 저장하는 방법에 대해 알아봤습니다😁

profile
선한 영향력으로 세상을 변화시키는 새싹개발자

0개의 댓글

관련 채용 정보