본문 바로가기

더 나은 엔지니어가 되기 위해/지금은 안쓰는 자바

[스프링 부트 개념과 활용] 데이터 3. DB 초기화, 마이그레이션

인프런에서 백기선님의 스프링부트 개념과 활용 강의를 듣고, 개인적으로 공부하며 핵심만 정리한 글입니다.

데이터베이스 초기화

1) JPA 를 이용한 초기화

EntityJPA Repository 만 설정해놓으면, 테스팅 코드에서는 테이블이 생성되어 잘 돌아가지만, Application 을 구동하면 그렇지 않다. 애초에 테이블 생성하는 코드가 없어서 그렇다.

따라서 Application 구동 시, 테이블을 생성하거나 혹은 수정하거나, 검증하거나 하는 등의 일을 설정해줄 필요가 있는데 application.properties 에서 이를 설정해줄 수 있다.

spring.jpa.generate-ddl=true
spring.jpa.hibernate.ddl-auto=create

위와 같이 설정값을 주면, Application 구동할 때마다, Entity 로 정의된 테이블을 생성해준다.
spring.jpa.hibernate.ddl-auto 의 값으론 다음이 있다.

  • create
    • 기존의 테이블이 있다면 지우고, 새로 만듬.
  • create-drop
    • 테이블을 새로 만들고, 앱이 꺼지기 전에 지운다.
  • update
    • Entity 에서 추가된 필드를 테이블에 반영한다.
  • validate
    • Entity 와 테이블의 정합성이 맞는지 검증한다. (안맞으면 오류를 냄)

또 다음의 설정 값을 주면, SQL 이 콘솔에 찍힌다.

spring.jpa.show-sql=true

2) SQL 스크립트를 이용한 초기화

JPA 를 사용하지 않는 환경이라면 schema.sql 로 앱 구동시 실행될 SQL 문을 미리 정의할 수 있다.
resources/schema.sql 을 만들어 다음과 같이 작성해준다.

drop table account if exists
drop sequence if exists hibernate_sequence
create sequence hibernate_sequence start with 1 increment by 1
create table account (id bigint not null, password varchar(255), username varchar(255), primary key (id))

이제 spring.jpa.generate-ddl=false 로 주어 JPA 를 이용한 초기화 설정을 끄자.
Application 을 구동하면, 이제 schema.sql 로 데이터베이스 초기화 이뤄지는 것을 볼 수 있다.

데이터베이스 마이그레이션

마이그레이션은 데이터베이스의 스키마의 변경사항을 기록하는 일종의 버전관리 기능이다.
여기서는 이러한 툴로 Flyway 를 사용해본다.

1) dependency 추가

pom.xml 에 다음 라이브러리를 추가한다.

<dependency>
  <groupId>org.flywaydb</groupId>
  <artifactId>flyway-core</artifactId>
</dependency>

2) DB 띄우기

docker 를 이용하여 PostgreSQL 을 띄운다.

$ docker run -p 5432:5432 -e POSTGRES_PASSWORD=pass -e POSTGRES_USER=heumsi -e POSTGRES_DB=springboot --name postgres_boot -d postgres

간단히 해석해보면,

  • localhost5432 포트를 docker container 5432 포트와 매핑시킨다.
  • -e 로 환경 변수를 설정한다.
    • POSTGRES_USERPOSTGRES_PASSWORD 를 설정한다
    • POSTGRES_DB 의 이름은 springboot 로 설정한다.
  • container 의 이름은 postgres_boot 로 한다.
  • -d 로 데몬(백그라운드에서 돌아가는 앱)으로 실행시킨다.
  • postgres 이미지를 다운받아 사용한다.

3) application.properties 설정

application.properties 를 다음과 같이 설정한다.

spring.datasource.url=jdbc:postgresql://localhost:5432/springboot
spring.datasource.username=heumsi
spring.datasource.password=pass

spring.jpa.hibernate.ddl-auto=validate
spring.jpa.generate-ddl=false
spring.jpa.show-sql=true

spring.jpa.hibernate.ddl-auto 의 값을 validate 로 줌으로써, 실제 DB 와 Entity 가 일치하는지 검증만 한다.

4) Flyway 설정

resources/db/migration 디렉토리를 만든 후, 이 디렉토리 안에 V1__init.sql 을 다음과 같이 작성한다.

drop table if exists account;
drop sequence if exists hibernate_sequence;
create sequence hibernate_sequence start with 1 increment by 1;
create table account (id bigint not null, email varchar(255), password varchar(255), username varchar(255), primary key (id));

즉, 앱이 구동될 때 위 스키마가 flyway 에 의해 실행된다.
이후, spring.jpa.hibernate.ddl-auto=validate 설정에 의해, 이렇게 만든 테이블이 Entity 와 일치하는지 검증하게 된다.

이제 Entity 역할을 하고있는 Accountactive 라는 속성을 추가했다고 하자.

@Entity
public class Account {
  ..
  private boolean active;
  ...
}

앱을 다시 구동하면 EntityV1__init.sql 의 스키마가 맞지않아 validate 에서 에러가 난다.

이제 스키마를 Entity 에 맞게 수정해줘야한다.
resources/db/migration/V2__add_active.sql 을 다음과 같이 작성하자.

ALTER TABLE account ADD COLUMN active BOOLEAN;

그리고 다시 앱을 작동시키면 이번에는 V2__add_active.sql 이 실행되어 다시 잘 돌아가는 것을 확인할 수 있다.

DB 테이블을 확인해보면 flyway_schema_history 테이블이 만들어진 것을 확인할 수 있다.

이 테이블에는 다음과 같이 스키마 변경 이록이 남는다.