Back-end/Spring

SpringBoot - 데이터베이스 Migration(마이그레이션)

Tigger 2020. 6. 28. 00:06

데이터베이스 Migration(마이그레이션)

스키마 혹은 데이터를 변경할 때 버전관리 형식으로 관리가 가능합니다. 대표적으로 Flyway와 Liquibase가 있습니다. 이중에 Flyway를 대표로 삼아 공부해보겠습니다.

도중 나오는 코드들은 이전 포스트에서 그대로 가져왔습니다.
코드가 필요하시면 JPA 연동하기 포스팅을 참고하시면 됩니다.
참고자료 : 스프링공식홈페이지, flyway홈페이지

Flyway 의존성 추가

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

 

JPA

의존성을 추가합니다.

마이그레이션

마이그레이션 디렉토리

  • /src/resources에 db/migration 경로를 생성합니다.
  • spring.flyway.locations 을 활용하여도 됩니다.

마이그레이션 파일 이름

  • V숫자__이름.sql (언더바(_) 두개입니다.)
  • V는 꼭 대문자로
  • 숫자는 순차적으로 (타임스탬프 권장)
  • 이름은 가능한 서술적으로 작성

마이그레이션 사용

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));

 

JPA

JPA 연동시 출력됐던 스키마를 sql문 안에 선언합니다. 그리고 애플리케이션을 실행합니다.

ps. 제가 선택한 postgres는 문법이 다르기 때문에 위 코드로 수정하였습니다.

JPA

flyway가 실행되면서 테이블이 account와 함께 flyway_schema_history가 함께 생성되었습니다. 이 테이블에는 앞으로 추가할 쿼리에 대해서 순서대로 기록해줍니다.

Entity 클래스에 컬럼이 추가되면?

@Entity
public class Account {

    @Id
    @GeneratedValue
    private Long id;
    private String username;
    private String password;
    private String email;
    private boolean active;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public boolean isActive() {
        return active;
    }

    public void setActive(boolean active) {
        this.active = active;
    }


    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Account account = (Account) o;
        return active == account.active &&
                Objects.equals(id, account.id) &&
                Objects.equals(username, account.username) &&
                Objects.equals(password, account.password) &&
                Objects.equals(email, account.email);
    }

    @Override
    public int hashCode() {
        return Objects.hash(id, username, password, email, active);
    }
}

기존 email까지 있었던 컬럼에서 boolean 타입인 active를 추가했습니다. 그리고 spring.jpa.hibernate.ddl-auto=validate 로 Entity 클래스와 운영 DB와 연동 되는지 확인하겠습니다.

두 번째 쿼리니 V2로 동일 경로에 만들어준 후 실행합니다.(절대 첫 번째 sql파일은 손대지 않습니다.)

ALTER TABLE account ADD COLUMN active BOOLEAN;

 

JPA

테이블에 컬럼이 추가된 것을 알 수 있습니다.
만약 V2 쿼리 없이 validate 했다면 Entity와 DB와의 연동은 되지 않았을 것입니다.
이유는 active에 해당되는 DB 컬럼이 없기 때문입니다.