Junjangsee's Blog

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

2019-05-14

images

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

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

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

Flyway 의존성 추가

1
2
3
4
<dependency>
<groupId>org.flywaydb</groupId>
<artifactId>flyway-core</artifactId>
</dependency>

JPA 의존성을 추가합니다.


마이그레이션

마이그레이션 디렉토리

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


마이그레이션 파일 이름

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


마이그레이션 사용

1
2
3
4
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 클래스에 컬럼이 추가되면?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
@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파일은 손대지 않습니다.)

1
ALTER TABLE account ADD COLUMN active BOOLEAN;

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