이번 velog에서는 SpringBoot로 DB에 Map<String,List<String>>
저장하는 방법에 대해 알아볼게요
여러 데이타들 저장할 때, 순차적으로 저장하는게 아니라 key
와 value
로 저장을 하는데. key
라는 이름을 가지고 그에 해당하는 value
를 저장합니다. -> key
는 중복이 불가능합니다.
@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과 같은 타입으로 변환해줘야 합니다.
@OneToMany
혹은 @ManyToOne
처럼 collection을 엔티티로 사용하는 것이 아니라. String
이나 Embedded
처럼 Type을 컬렉션으로 사용하고 싶을 때 쓰는 어노테이션입니다.
🤔 : 왜??
🧐 : Mysql과 같은 관계형 DB(Relation DB)에서는 Collection을 담을 수 있는 구조가 없어서 따로 테이블을 만들어 저장해야 합니다. ElementCollection은 해당 필드가 컬렉션 객체임을 JPA에게 알려주고, Embeddable Class를 생성하고 @OneToMany
관계를 만들어줍니다. 그리고 @ElementCollection
은 @CollectionTable
과 같이 사용됩니다.
매핑할 테이블에 관한 정보를 지정하는 어노테이션입니다. 만약 생략한다면 디폴트값인 {엔티티이름}_{컬렉션 필드 이름}
을 이용해서 매핑합니다.
이는 Embedd할 Tool과 관련이 있어서 Tool.java를 설명하면서 같이 설명하겠습니다.
아래는 List<String>
타입 변수를 다른 embeddable entity로 만든 코드입니다.
@Embeddable //이 엔티티가 다른 값type에 내장(embedded)될 수 있는 타입이다!
@NoArgsConstructor
@AllArgsConstructor
@Getter
public class Tool {
@Convert(converter = ListStringConverter.class)
private List<String> tool;
}
Map
형식은 Key
와 value
로 이뤄진다고 했습니다. Project.java에서 사용하는 @MapKeyColumn
은 String
으로 된 Key Column을 만들고 이를 key
로 사용한다는 뜻입니다. 이와 비슷한 @MapKey
가 있지만, 이 어노테이션 사용하려면 Tool.java에서 tool_id 필드를 생성해줘야 합니다.
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(","));
}
}
"tool": {
"개발": ["springboot", "git"],
"디자인": ["피그마", "피그잼"]
}
이렇게 프런트엔드에서 준다면
이렇게 DB에 저장됩니다.
이렇게 해서 Map<String,List<String>>
을 받아서 DB에 저장하는 방법에 대해 알아봤습니다😁