[F-Lab 모각코 챌린지 65일차] WAS 시작시 DB에 값넣기

부추·2023년 8월 5일
0

F-Lab 모각코 챌린지

목록 보기
65/66

DB 값넣기

레시피에 존재할 태그의 목록이 있다. 최초엔 레시피의 카테고리를 나눠서, 사용자들이 카테고리별로 레시피를 나눌 수 있는 기능을 만들고 싶었는데 멘토님께서 레시피에 달린 태그 기능으로 만들면 기능의 개발이나 확장성 측면에서 더 좋을 것 같다고 조언해주셨다.

생각해보니 카테고리란 아예 존재하지 않을 수도 있고, 하나의 태그 타입에도 여러 개의 태그가 존재할 수도 있어서 태그가 레시피와 일대다 연관관계를 맺을 수 있으면 훨씬 좋을 것 같다!!

엔티티 클래스는 아래와 같이 작성될 예정이다.

@Entity
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Getter
public class Tag {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column
    private TagType tagType;

    @Column
    private TagName tagName;
}

TagType은 "종류별", "상황별" 등 말 그대로 어떤 종류의 태그인지를 결정하고, TagName은 레시피 엔티티가 가진 실제 태그, 즉 "디저트"나 "찌개"(종류별일 경우) 혹은 "손님 접대용"이나 "초간단" 등이 존재한다.


전반적으로 "만개의 레시피" 사이트의 "분류" 기능과 유사하게 만들 계획이다.

생각해보아야 하는 점이 있다. Tag는 "정해진 레코드"라는 점이다. 게다가 만개의 레시피를 보면 알겠지만 상용화되는 서비스임에도 갯수가 많지 않다. 한 태그 타입당 태그들이 열댓개정도 되니 많아봤자 5-60개 정도 되는 것이다.

생각을 해봐야한다. Tag가 독립적인 엔티티가 될 수 있는가? 최근에 본 DDD 책에서 별도의 생명 주기를 가진 애그리거트가 아닌 밸류 값에 대해선 @ElementCollection + @CollectionTable을 통해 밸류 컬렉션을 별도 테이블로 만들 수 있다고 책에 나오는데 사용 시도를 하는게 맞을지 고민했다.


관련 내용은.. 나중에 공부하기로 하고. 일단 엔티티로 태그를 만들었을 경우, 어떻게 테이블 초기화를 할 수 있을지 고민해보자.



1) Using Data SQL Initialization

src/main/resources 디렉토리에 데이터 삽입 문이 있는 SQL 스크립트를 배치할 수 있다. 파일 이름은 data.sql 혹은 import.sql등이다. Spring Boot는 애플리케이션 시작 중에 이러한 스크립트를 자동으로 실행합는데, 이 접근 방식은 Java 코드 없이 간단한 데이터 seeding을 시도하는데 유용하다. 앞서 말했듯 태그 레코트가 많아봤자 5-60개 정도일테니 이를 이용하는 것도 나쁘지 않을듯.

2) Using Data Seeder Beans

CommandLineRunner 또는 ApplicationRunner를 구현하는 대신 전용 "시드" Bean을 생성하여 데이터를 데이터베이스에 삽입할 수 있다. 이러한 빈은 @Component로 구성할 수 있겠다. 혹은 Spring의 @PostConstruct 주석을 사용하여 bean이 초기화될 때 데이터 삽입 로직을 실행할 수도 있는데.. 이 작업 하나만을 위해 @PostConstruct를 하는 것은 좀.

3) Using Flyway or Liquibase

Flyway, Liquibase는 시간 경과에 따른 DB 스키마 및 데이터 변경 사항을 관리할 수 있는 데이터베이스 마이그레이션 솔루션이다. 이러한 솔루션들을 사용하여 초기 데이터 삽입을 포함해, 데이터베이스 변경 사항의 버전을 제어할 수 있다. DB 형상관리 툴이라고 생각하면 될 듯? 100개도 안되는 데이터 시딩에 솔루션을 따로 공부해 사용하기엔 오버엔지니어링이 될 것 같아서 패스!

4) Using CommandLineRunner and Profiles

spring이 제공하는 profiles 기능을 이용해 각 환경에서 구동되는 active profiles(local, test, prod등)을 기반으로 특정 데이터를 조건부로 삽입할 수 있다. @Profile 주석을 CommandLineRunner와 함께 사용할한다. 각 프로필에 대해 서로 다른 데이터 초기화 논리를 정의하면 Spring Boot가 활성 프로필을 기반으로 적절한 runner을 실행시킬 수 있다. 특히 이 방법의 경우


CommandLineRunner 사용해보기

방법은 전혀 어렵지 않다.

  1. CommandLineRunner 인터페이스를 구현하고 run() 메소드를 재정의하는 component를 생성한다.
  2. run() 메소드에서 특정 데이터를 데이터베이스에 삽입하는 로직을 작성한다.

만약 MyRepositoryMyEntity를 삽입해야하는 상황이라면 아래와 같이 구성하면 되는 것이다.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;

@Component
public class DatabaseInitializer implements CommandLineRunner {

    @Autowired
    private MyRepository myRepository;

    @Override
    public void run(String... args) {
        MyEntity entity1 = new MyEntity("Data 1");
        MyEntity entity2 = new MyEntity("Data 2");

        myRepository.save(entity1);
        myRepository.save(entity2);

        // 다른 DB init 로직..
    }
}

방법은 확실히 충격적으로 간단한데.. 게다가 여러 개의 서버 인스턴스를 띄웠을 경우 profiles를 다르게 설정하면 하나의 서버가 구동될 때만 DB initializing을 할 수도 있다.

그러나 아직 collection을 쓸지, 다대다를 쓸지 일대다를 쓸지마저도 정하지 않았기 때문에 ㅠㅇㅠ. 조금만 더 고민해봐야겠다.

profile
부추튀김인지 부추전일지 모를 정도로 빠싹한 부추전을 먹을래

0개의 댓글