1. 소개

이 사용방법(예제)에서는 Flyway의 주요 개념 과 이 프레임워크를 사용하여 애플리케이션의 데이터베이스 스키마를 안정적이고 쉽게 지속적으로 리모델링하는 방법을 살펴봅니다. 또한 Maven Flyway 플러그인을 사용하여 인메모리 H2 데이터베이스를 관리하는 예를 제시합니다.

Flyway는 마이그레이션을 사용하여 한 버전에서 다음 버전으로 데이터베이스를 업데이트합니다. 데이터베이스별 구문을 사용하여 SQL로 마이그레이션을 작성하거나 고급 데이터베이스 변환을 위해 Java로 마이그레이션을 작성할 수 있습니다.

마이그레이션은 버전을 지정하거나 반복할 수 있습니다. 전자는 고유한 버전이 있으며 정확히 한 번만 적용됩니다. 후자는 버전이 없습니다. 대신 체크섬이 변경될 때마다 (재)적용됩니다.

단일 마이그레이션 실행 내에서 반복 가능한 마이그레이션은 보류 중인 버전이 지정된 마이그레이션이 실행된 후 항상 마지막에 적용됩니다. 반복 가능한 마이그레이션은 설명 순서대로 적용됩니다. 단일 마이그레이션의 경우 모든 명령문이 단일 데이터베이스 트랜잭션 내에서 실행됩니다.

이 예제에서는 주로 Maven 플러그인을 사용하여 데이터베이스 마이그레이션을 수행하는 방법에 중점을 둘 것입니다.

2. 플라이웨이 메이븐 플러그인

Flyway Maven 플러그인을 설치하려면 다음 플러그인 정의를 pom.xml에 추가해 보겠습니다 .

<plugin>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-maven-plugin</artifactId>
    <version>4.0.3</version> 
</plugin>

플러그인의 최신 버전은 Maven Central 에서 사용할 수 있습니다 .

이 Maven 플러그인을 네 가지 방법으로 구성할 수 있습니다. 다음 섹션에서는 이러한 각 옵션을 살펴보겠습니다.

구성 가능한 모든 속성 List을 보려면 설명서참조하십시오 .

2.1. 플러그인 구성

pom.xml 의 플러그인 정의에서 <configuration> 태그 를 통해 플러그인을 직접 구성 할 수 있습니다 .

<plugin>
    <groupId>org.flywaydb</groupId>
    <artifactId>flyway-maven-plugin</artifactId>
    <version>4.0.3</version>
    <configuration>
        <user>databaseUser</user>
        <password>databasePassword</password>
        <schemas>
            <schema>schemaName</schema>
        </schemas>
        ...
    </configuration>
</plugin>

2.2. 메이븐 속성

pom에서 구성 가능한 속성 을 Maven 속성 으로 지정하여 플러그인을 구성 할 수도 있습니다 .

<project>
    ...
    <properties>
        <flyway.user>databaseUser</flyway.user>
        <flyway.password>databasePassword</flyway.password>
        <flyway.schemas>schemaName</flyway.schemas>
        ...
    </properties>
    ...
</project>

2.3. 외부 구성 파일

또 다른 옵션은 별도의 .properties 파일 에 플러그인 구성제공하는 것입니다 .

flyway.user=databaseUser
flyway.password=databasePassword
flyway.schemas=schemaName
...

기본 구성 파일 이름은 flyway.properties 이며 pom.xml 파일 과 동일한 디렉토리에 있어야 합니다 . 인코딩은 flyway.encoding에 의해 지정됩니다 (기본값은 UTF-8 ).

다른 이름(예: customConfig.properties )을 구성 파일로 사용하는 경우 Maven 명령을 호출할 때 이를 명시적으로 지정해야 합니다.

$ mvn -Dflyway.configFile=customConfig.properties

2.4. 시스템 속성

마지막으로 명령줄에서 Maven을 호출할 때 모든 구성 속성을 시스템 속성 으로 지정할 수도 있습니다 .

$ mvn -Dflyway.user=databaseUser -Dflyway.password=databasePassword 
  -Dflyway.schemas=schemaName

다음은 구성이 둘 이상의 방식으로 지정된 경우의 우선 순위입니다.

  1. 시스템 속성
  2. 외부 구성 파일
  3. 메이븐 속성
  4. 플러그인 구성

3. 마이그레이션 예

이 섹션에서는 Maven 플러그인을 사용하여 데이터베이스 스키마를 메모리 내 H2 데이터베이스로 마이그레이션하는 데 필요한 단계를 안내합니다. 외부 파일을 사용하여 Flyway를 구성합니다.

3.1. POM 업데이트

먼저 H2를 의존성으로 추가해 보겠습니다.

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.196</version>
</dependency>

다시 말하지만, Maven Central에서 사용 가능한 최신 버전의 드라이버를 확인할 수 있습니다 . 또한 앞에서 설명한 대로 Flyway 플러그인을 추가합니다.

3.2. 외부 파일을 사용하여 Flyway 구성

다음으로 다음 콘텐츠 $PROJECT_ROOT에 myFlywayConfig.properties만듭니다 .

flyway.user=databaseUser
flyway.password=databasePassword
flyway.schemas=app-db
flyway.url=jdbc:h2:mem:DATABASE
flyway.locations=filesystem:db/migration

위의 구성은 마이그레이션 스크립트가 db/migration 디렉토리에 있음을 지정합니다. databaseUserdatabasePassword 를 사용하여 메모리 내 H2 인스턴스에 연결 합니다 .

애플리케이션 데이터베이스 스키마는 app-db 입니다.

물론 flyway.user, flyway.passwordflyway.url 을 각각 자체 데이터베이스 사용자 이름, 데이터베이스 암호 및 데이터베이스 URL로 바꿉니다 .

3.3. 첫 번째 마이그레이션 정의

Flyway 는 마이그레이션 스크립트에 대해 다음 명명 규칙을 따릅니다.

<접두사><버전>__<설명>.sql

어디에:

  • <Prefix> – 기본 접두사는 V 이며, 위의 구성 파일에서 flyway.sqlMigrationPrefix 속성을 사용하여 변경할 수 있습니다.
  • <버전> – 마이그레이션 버전 번호입니다. 주 버전과 부 버전은 밑줄 로 구분할 수 있습니다 . 마이그레이션 버전은 항상 1로 시작해야 합니다.
  • <설명> – 마이그레이션에 대한 텍스트 설명입니다. 이중 밑줄은 버전 번호와 설명을 구분합니다.

예: V1_1_0__my_first_migration.sql

따라서 직원 테이블을 생성하기 위한 SQL 지침이 포함 V1_0__create_employee_schema.sql 이라는 마이그레이션 스크립트를 사용하여 $PROJECT_ROOTdb/migration 디렉터리를 생성해 보겠습니다 .

CREATE TABLE IF NOT EXISTS `employee` (

    `id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
    `name` varchar(20),
    `email` varchar(50),
    `date_of_birth` timestamp

)ENGINE=InnoDB DEFAULT CHARSET=UTF8;

3.4. 마이그레이션 실행

다음으로 $PROJECT_ROOT 에서 다음 Maven 명령을 호출하여 데이터베이스 마이그레이션을 실행합니다.

$ mvn clean flyway:migrate -Dflyway.configFile=myFlywayConfig.properties

이는 첫 번째 성공적인 마이그레이션으로 이어집니다.

이제 데이터베이스 스키마는 다음과 같아야 합니다.

employee:
+----+------+-------+---------------+
| id | name | email | date_of_birth |
+----+------+-------+---------------+

더 많은 마이그레이션을 수행하기 위해 정의 및 실행 단계를 반복할 수 있습니다.

3.5. 두 번째 마이그레이션 정의 및 실행

다음 두 쿼리가 포함된 V2_0_create_department_schema.sql 이라는 이름의 두 번째 마이그레이션 파일을 만들어 두 번째 마이그레이션이 어떻게 보이는지 보겠습니다 .

CREATE TABLE IF NOT EXISTS `department` (

`id` int NOT NULL AUTO_INCREMENT PRIMARY KEY,
`name` varchar(20)

)ENGINE=InnoDB DEFAULT CHARSET=UTF8; 

ALTER TABLE `employee` ADD `dept_id` int AFTER `email`;

그런 다음 처음과 마찬가지로 유사한 마이그레이션을 실행합니다.

이제 직원 과 새 테이블에 새 열을 추가하도록 데이터베이스 스키마가 변경되었습니다 .

employee:
+----+------+-------+---------+---------------+
| id | name | email | dept_id | date_of_birth |
+----+------+-------+---------+---------------+
department:
+----+------+
| id | name |
+----+------+

마지막으로 다음 Maven 명령을 호출하여 두 마이그레이션이 모두 성공했는지 확인할 수 있습니다.

$ mvn flyway:info -Dflyway.configFile=myFlywayConfig.properties

4. IntelliJ IDEA에서 버전이 지정된 마이그레이션 생성

마이그레이션을 수동으로 작성하려면 많은 시간이 걸립니다. 대신 JPA 엔티티를 기반으로 생성할 수 있습니다. JPA Buddy 라는 IntelliJ IDEA용 플러그인을 사용하여 이를 달성할 수 있습니다 .

차등 버전 마이그레이션을 생성하려면 플러그인을 설치하고 JPA 구조 패널에서 작업을 호출하기만 하면 됩니다.

비교하려는 소스(데이터베이스 또는 JPA 엔터티)와 대상(데이터베이스 또는 데이터 모델 스냅샷)을 선택하기만 하면 됩니다. 그러면 JPA Buddy는 애니메이션에 표시된 대로 마이그레이션생성합니다 .

JPA Buddy의 또 다른 장점은 Java와 데이터베이스 유형 간의 매핑을 정의하는 기능입니다. 또한 Hibernate 사용자 정의 유형 및 JPA 변환기에서 올바르게 작동합니다.

5. Spring Boot에서 Flyway 비활성화

때로는 특정 상황에서 Flyway 마이그레이션비활성화 해야 할 수도 있습니다 .

예를 들어 테스트 중에 엔터티를 기반으로 데이터베이스 스키마를 생성하는 것이 일반적입니다. 이러한 상황에서 테스트 프로필에서 Flyway를 비활성화할 수 있습니다 .

Spring Boot에서 얼마나 쉬운지 봅시다 .

5.1. 스프링 부트 1.x

우리가 할 필요가있다 설정된 flyway.enabled 우리의 재산 application-test.properties 파일 :

flyway.enabled=false

5.2. 스프링 부트 2.x

최신 버전의 Spring Boot에서는 이 속성이 spring.flyway.enabled 로 변경되었습니다 .

spring.flyway.enabled=false

5.3 빈 FlywayMigrationStrategy

시작 시 자동 Flyway 마이그레이션비활성화하고 마이그레이션을 수동으로 트리거할 수 있는 경우 위에 설명된 속성을 사용하는 것은 좋은 선택이 아닙니다.

그런 상황에서 Spring Boot는 더 이상 Flyway 빈을 자동 구성하지 않기 때문입니다 . 결과적으로, 우리는 그것을 우리 스스로 제공해야 하고, 이것은 그다지 편리하지 않습니다.

따라서 이것이 사용 사례인 경우 Flyway를 활성화된 상태로 두고 빈 FlywayMigrationStrategy를 구현할 수 있습니다 .

@Configuration
public class EmptyMigrationStrategyConfig {

    @Bean
    public FlywayMigrationStrategy flywayMigrationStrategy() {
        return flyway -> {
            // do nothing  
        };
    }
}

이렇게 하면 응용 프로그램 시작 시 Flyway 마이그레이션 이 효과적으로 비활성화 됩니다 .

그러나 수동으로 마이그레이션을 트리거할 수는 있습니다.

@RunWith(SpringRunner.class)
@SpringBootTest
public class ManualFlywayMigrationIntegrationTest {

    @Autowired
    private Flyway flyway;

    @Test
    public void skipAutomaticAndTriggerManualFlywayMigration() {
        flyway.migrate();
    }
}

6. 플라이웨이 작동 방식

우리가 이미 적용한 마이그레이션과 시기를 추적하기 위해 스키마에 특수 부기 테이블을 추가합니다. 이 메타데이터 테이블은 마이그레이션 체크섬과 마이그레이션 성공 여부도 추적합니다.

프레임워크는 진화하는 데이터베이스 스키마를 수용하기 위해 다음 단계를 수행합니다.

  1. 메타데이터 테이블( 기본적으로 SCHEMA_VERSION) 을 찾기 위해 데이터베이스 스키마를 확인합니다 . 메타데이터 테이블이 없으면 새로 생성합니다.
  2. 사용 가능한 마이그레이션에 대해 애플리케이션 클래스 경로를 스캔합니다.
  3. 메타데이터 테이블과 마이그레이션을 비교합니다. 버전 번호가 현재로 표시된 버전보다 낮거나 같으면 무시됩니다.
  4. 나머지 마이그레이션을 보류 중인 마이그레이션으로 표시합니다. 버전 번호를 기준으로 정렬되어 순서대로 실행됩니다.
  5. 각 마이그레이션이 적용될 때마다 메타데이터 테이블이 그에 따라 업데이트됩니다.

7. 명령

Flyway는 데이터베이스 마이그레이션을 관리하기 위해 다음과 같은 기본 명령을 지원합니다.

  • Info : 데이터베이스 스키마의 현재 상태/버전을 출력한다. 보류 중인 마이그레이션, 적용된 마이그레이션, 적용된 마이그레이션의 상태 및 적용된 시간을 인쇄합니다.
  • 마이그레이션 : 데이터베이스 스키마를 현재 버전으로 마이그레이션합니다. 클래스 경로에서 사용 가능한 마이그레이션을 검색하고 보류 중인 마이그레이션을 적용합니다.
  • Baseline : baselineVersion 을 포함한 모든 마이그레이션을 제외하고 기존 데이터베이스를 기준으로 합니다. Baseline은 기존 데이터베이스에서 Flyway로 시작하는 데 도움이 됩니다. 그런 다음 최신 마이그레이션을 정상적으로 적용할 수 있습니다.
  • Validate : 사용 가능한 마이그레이션에 대해 현재 데이터베이스 스키마의 유효성을 검사합니다.
  • 복구 : 메타데이터 테이블을 복구 합니다.
  • 정리 : 구성된 스키마의 모든 개체를 삭제합니다. 물론프로덕션 데이터베이스에서 clean사용해서는 안됩니다.

8. 결론

이 기사에서는 Flyway가 작동하는 방식과 이 프레임워크를 사용하여 애플리케이션 데이터베이스를 안정적으로 리모델링하는 방법을 배웠습니다.

이 기사와 함께 제공되는 코드는 GitHub에서 사용할 수 있습니다 .

Persistence footer banner