AI 지식 / / 2025. 10. 10. 06:39

[Spring Boot 번역] Database Initialization

출처: https://docs.spring.io/spring-boot/4.0-SNAPSHOT/how-to/data-initialization.html

SQL 데이터베이스는 스택이 무엇인지에 따라 다양한 방법으로 초기화될 수 있습니다. 물론 데이터베이스가 별도의 프로세스인 경우 수동으로 수행할 수도 있습니다. 스키마 생성을 위해서는 단일 메커니즘을 사용하는 것이 권장됩니다.

Initialize a Database Using Hibernate

spring.jpa.hibernate.ddl-auto를 설정하여 Hibernate의 데이터베이스 초기화를 제어할 수 있습니다. 지원되는 값은 none, validate, update, create, create-drop입니다.

Spring Boot는 임베디드 데이터베이스를 사용하는지 여부에 따라 기본값을 선택합니다. 임베디드 데이터베이스는 Connection 타입과 JDBC url을 확인하여 식별됩니다. hsqldb, h2, derby는 임베디드 데이터베이스이며 나머지는 그렇지 않습니다.

임베디드 데이터베이스가 식별되고 스키마 관리자(Flyway 또는 Liquibase)가 감지되지 않은 경우, ddl-auto는 기본적으로 create-drop으로 설정됩니다. 다른 모든 경우에는 none이 기본값입니다.

인메모리에서 '실제' 데이터베이스로 전환할 때 새 플랫폼에서 테이블과 데이터의 존재를 가정하지 않도록 주의해야 합니다. ddl-auto를 명시적으로 설정하거나 다른 메커니즘 중 하나를 사용하여 데이터베이스를 초기화해야 합니다.

org.hibernate.SQL 로거를 활성화하여 스키마 생성을 출력할 수 있습니다. 디버그 모드를 활성화하면 자동으로 수행됩니다.

또한 Hibernate가 처음부터 스키마를 생성하는 경우(즉, ddl-auto 속성이 create 또는 create-drop으로 설정된 경우) classpath의 루트에 있는 import.sql이라는 파일이 시작 시 실행됩니다. 이는 신중하게 사용하면 데모 및 테스트에 유용할 수 있지만 프로덕션 환경의 classpath에는 사용하지 않는 것이 좋습니다. 이것은 Hibernate 기능입니다(Spring과는 관련이 없습니다).

Initialize a Database Using Basic SQL Scripts

Spring Boot는 JDBC DataSource 또는 R2DBC ConnectionFactory의 스키마(DDL 스크립트)를 자동으로 생성하고 데이터(DML 스크립트)를 초기화할 수 있습니다.

기본적으로 optional:classpath*:schema.sql에서 스키마 스크립트를 로드하고 optional:classpath*:data.sql에서 데이터 스크립트를 로드합니다. 이러한 스키마 및 데이터 스크립트의 위치는 각각 spring.sql.init.schema-locationsspring.sql.init.data-locations를 사용하여 사용자 정의할 수 있습니다.

optional: 접두사는 파일이 존재하지 않아도 애플리케이션이 시작된다는 것을 의미합니다. 파일이 없을 때 애플리케이션 시작이 실패하도록 하려면 optional: 접두사를 제거하세요.

또한 Spring Boot는 optional:classpath*:schema-${platform}.sqloptional:classpath*:data-${platform}.sql 파일(있는 경우)을 처리합니다. 여기서 ${platform}spring.sql.init.platform의 값입니다. 이를 통해 필요한 경우 데이터베이스별 스크립트로 전환할 수 있습니다. 예를 들어, 데이터베이스의 벤더 이름(hsqldb, h2, oracle, mysql, postgresql 등)으로 설정할 수 있습니다.

기본적으로 SQL 데이터베이스 초기화는 임베디드 인메모리 데이터베이스를 사용할 때만 수행됩니다. 유형에 관계없이 항상 SQL 데이터베이스를 초기화하려면 spring.sql.init.modealways로 설정하세요. 마찬가지로 초기화를 비활성화하려면 spring.sql.init.modenever로 설정하세요.

기본적으로 Spring Boot는 스크립트 기반 데이터베이스 이니셜라이저의 fail-fast 기능을 활성화합니다. 이는 스크립트에서 예외가 발생하면 애플리케이션이 시작되지 않는다는 것을 의미합니다. spring.sql.init.continue-on-error를 설정하여 이 동작을 조정할 수 있습니다.

스크립트 기반 DataSource 초기화는 기본적으로 JPA EntityManagerFactory 빈이 생성되기 전에 수행됩니다. schema.sql은 JPA 관리 엔터티의 스키마를 생성하는 데 사용될 수 있으며 data.sql은 이를 채우는 데 사용될 수 있습니다.

여러 데이터 소스 초기화 기술을 사용하는 것은 권장하지 않지만, 스크립트 기반 DataSource 초기화가 Hibernate에 의해 수행된 스키마 생성을 기반으로 할 수 있도록 하려면 spring.jpa.defer-datasource-initializationtrue로 설정하세요. 이렇게 하면 EntityManagerFactory 빈이 생성되고 초기화된 후까지 데이터 소스 초기화가 지연됩니다. 그런 다음 schema.sql을 사용하여 Hibernate에 의해 수행된 스키마 생성에 추가할 수 있으며 data.sql을 사용하여 채울 수 있습니다.

초기화 스크립트는 한 줄 주석에 --를, 블록 주석에 /* */를 지원합니다. 다른 주석 형식은 지원되지 않습니다.

Flyway 또는 Liquibase와 같은 상위 레벨 데이터베이스 마이그레이션 도구를 사용하는 경우 이를 단독으로 사용하여 스키마를 생성하고 초기화해야 합니다. Flyway 또는 Liquibase와 함께 기본 schema.sqldata.sql 스크립트를 사용하는 것은 권장되지 않으며 향후 릴리스에서 지원이 제거됩니다.

상위 레벨 데이터베이스 마이그레이션 도구를 사용하여 테스트 데이터를 초기화해야 하는 경우 FlywayLiquibase에 대한 섹션을 참조하세요.

Initialize a Spring Batch Database

Spring Batch를 사용하는 경우 대부분의 인기 있는 데이터베이스 플랫폼에 대한 SQL 초기화 스크립트가 사전 패키지되어 제공됩니다. Spring Boot는 데이터베이스 유형을 감지하고 시작 시 해당 스크립트를 실행할 수 있습니다. 임베디드 데이터베이스를 사용하는 경우 기본적으로 이 작업이 수행됩니다. 다음 예제와 같이 모든 데이터베이스 유형에 대해 활성화할 수도 있습니다:

Properties

spring.batch.jdbc.initialize-schema=always

YAML

spring:
  batch:
    jdbc:
      initialize-schema: "always"

spring.batch.jdbc.initialize-schemanever로 설정하여 초기화를 명시적으로 끌 수도 있습니다.

Use a Higher-level Database Migration Tool

Spring Boot는 두 가지 상위 레벨 마이그레이션 도구를 지원합니다: FlywayLiquibase.

Execute Flyway Database Migrations on Startup

시작 시 Flyway 데이터베이스 마이그레이션을 자동으로 실행하려면 적절한 Flyway 모듈을 classpath에 추가하세요.

인메모리 및 파일 기반 데이터베이스는 org.flywaydb:flyway-core에서 지원됩니다. 그렇지 않으면 데이터베이스별 모듈이 필요합니다. 예를 들어 PostgreSQL에는 org.flywaydb:flyway-database-postgresql을, MySQL에는 org.flywaydb:flyway-mysql을 사용하세요. 자세한 내용은 Flyway 문서를 참조하세요.

일반적으로 마이그레이션은 V<VERSION>__<NAME>.sql 형식의 스크립트입니다(<VERSION>은 '1' 또는 '2_1'과 같이 밑줄로 구분된 버전). 기본적으로 이들은 classpath:db/migration이라는 디렉토리에 있지만 spring.flyway.locations를 설정하여 해당 위치를 수정할 수 있습니다. 이것은 하나 이상의 classpath: 또는 filesystem: 위치의 쉼표로 구분된 목록입니다. 예를 들어 다음 구성은 기본 classpath 위치와 /opt/migration 디렉토리 모두에서 스크립트를 검색합니다:

Properties

spring.flyway.locations=classpath:db/migration,filesystem:/opt/migration

YAML

spring:
  flyway:
    locations: "classpath:db/migration,filesystem:/opt/migration"

특수 {vendor} 플레이스홀더를 추가하여 벤더별 스크립트를 사용할 수도 있습니다. 다음을 가정합니다:

Properties

spring.flyway.locations=classpath:db/migration/{vendor}

YAML

spring:
  flyway:
    locations: "classpath:db/migration/{vendor}"

db/migration을 사용하는 대신 위의 구성은 데이터베이스 유형에 따라 사용할 디렉토리를 설정합니다(예: MySQL의 경우 db/migration/mysql). 지원되는 데이터베이스 목록은 DatabaseDriver에서 확인할 수 있습니다.

마이그레이션은 Java로도 작성할 수 있습니다. Flyway는 JavaMigration을 구현하는 모든 빈으로 자동 구성됩니다.

FlywayProperties는 Flyway 설정의 대부분과 마이그레이션을 비활성화하거나 위치 확인을 끌 수 있는 소수의 추가 속성을 제공합니다. 구성에 대한 더 많은 제어가 필요한 경우 FlywayConfigurationCustomizer 빈을 등록하는 것을 고려하세요.

Spring Boot는 Flyway.migrate()를 호출하여 데이터베이스 마이그레이션을 수행합니다. 더 많은 제어가 필요한 경우 FlywayMigrationStrategy를 구현하는 @Bean을 제공하세요.

Flyway는 SQL 및 Java 콜백을 지원합니다. SQL 기반 콜백을 사용하려면 classpath:db/migration 디렉토리에 콜백 스크립트를 배치하세요. Java 기반 콜백을 사용하려면 Callback을 구현하는 하나 이상의 빈을 생성하세요. 이러한 빈은 자동으로 Flyway에 등록됩니다. @Order를 사용하거나 Ordered를 구현하여 순서를 지정할 수 있습니다.

기본적으로 Flyway는 컨텍스트의 (@Primary) DataSource를 자동 연결하고 마이그레이션에 사용합니다. 다른 DataSource를 사용하려면 하나를 생성하고 해당 @Bean@FlywayDataSource로 표시할 수 있습니다. 이렇게 하고 두 개의 데이터 소스를 원하는 경우(예: 기본 자동 구성 DataSource를 유지함으로써) @Bean 어노테이션의 defaultCandidate 속성을 false로 설정해야 합니다. 또는 외부 속성에서 spring.flyway.[url,user,password]를 설정하여 Flyway의 네이티브 DataSource를 사용할 수 있습니다. spring.flyway.url 또는 spring.flyway.user를 설정하면 Flyway가 자체 DataSource를 사용하기에 충분합니다. 세 가지 속성 중 하나라도 설정되지 않은 경우 해당 spring.datasource 속성의 값이 사용됩니다.

Flyway를 사용하여 특정 시나리오에 대한 데이터를 제공할 수도 있습니다. 예를 들어 src/test/resources에 테스트별 마이그레이션을 배치할 수 있으며 애플리케이션이 테스트를 위해 시작될 때만 실행됩니다. 또한 프로파일별 구성을 사용하여 spring.flyway.locations를 사용자 정의하여 특정 프로파일이 활성화될 때만 특정 마이그레이션이 실행되도록 할 수 있습니다. 예를 들어 application-dev.properties에서 다음 설정을 지정할 수 있습니다:

Properties

spring.flyway.locations=classpath:/db/migration,classpath:/dev/db/migration

YAML

spring:
  flyway:
    locations: "classpath:/db/migration,classpath:/dev/db/migration"

이 설정을 사용하면 dev/db/migration의 마이그레이션은 dev 프로파일이 활성화될 때만 실행됩니다.

Execute Liquibase Database Migrations on Startup

시작 시 Liquibase 데이터베이스 마이그레이션을 자동으로 실행하려면 org.liquibase:liquibase-core를 classpath에 추가하세요.

org.liquibase:liquibase-core를 classpath에 추가하면 애플리케이션 시작 시와 테스트 실행 전 모두 데이터베이스 마이그레이션이 기본적으로 실행됩니다. 이 동작은 maintest 구성에서 서로 다른 값을 설정하여 spring.liquibase.enabled 속성을 사용하여 사용자 정의할 수 있습니다. 두 가지 다른 방법을 사용하여 데이터베이스를 초기화하는 것은 불가능합니다(예: 애플리케이션 시작에는 Liquibase, 테스트 실행에는 JPA).

기본적으로 마스터 변경 로그는 db/changelog/db.changelog-master.yaml에서 읽히지만 spring.liquibase.change-log를 설정하여 위치를 변경할 수 있습니다. YAML 외에도 Liquibase는 JSON, XML 및 SQL 변경 로그 형식을 지원합니다.

기본적으로 Liquibase는 컨텍스트의 (@Primary) DataSource를 자동 연결하고 마이그레이션에 사용합니다. 다른 DataSource를 사용해야 하는 경우 하나를 생성하고 해당 @Bean@LiquibaseDataSource로 표시할 수 있습니다. 이렇게 하고 두 개의 데이터 소스를 원하는 경우(예: 기본 자동 구성 DataSource를 유지함으로써) @Bean 어노테이션의 defaultCandidate 속성을 false로 설정해야 합니다. 또는 외부 속성에서 spring.liquibase.[driver-class-name,url,user,password]를 설정하여 Liquibase의 네이티브 DataSource를 사용할 수 있습니다. spring.liquibase.url 또는 spring.liquibase.user를 설정하면 Liquibase가 자체 DataSource를 사용하기에 충분합니다. 세 가지 속성 중 하나라도 설정되지 않은 경우 해당 spring.datasource 속성의 값이 사용됩니다.

컨텍스트, 기본 스키마 등과 같은 사용 가능한 설정에 대한 자세한 내용은 LiquibaseProperties를 참조하세요.

사용되기 전에 Liquibase 인스턴스를 사용자 정의하려는 경우 Customizer<Liquibase> 빈을 사용할 수도 있습니다.

Use Flyway for Test-only Migrations

테스트 데이터베이스를 채우는 Flyway 마이그레이션을 생성하려면 src/test/resources/db/migration에 배치하세요. 예를 들어 src/test/resources/db/migration/V9999__test-data.sql이라는 파일은 프로덕션 마이그레이션 이후에 실행되며 테스트를 실행하는 경우에만 실행됩니다. 이 파일을 사용하여 필요한 테스트 데이터를 생성할 수 있습니다. 이 파일은 uber jar 또는 컨테이너에 패키징되지 않습니다.

Use Liquibase for Test-only Migrations

테스트 데이터베이스를 채우는 Liquibase 마이그레이션을 생성하려면 프로덕션 변경 로그도 포함하는 테스트 변경 로그를 생성해야 합니다.

먼저 테스트를 실행할 때 다른 변경 로그를 사용하도록 Liquibase를 구성해야 합니다. 이를 수행하는 한 가지 방법은 Spring Boot test 프로파일을 생성하고 거기에 Liquibase 속성을 넣는 것입니다. 이를 위해 src/test/resources/application-test.properties라는 파일을 생성하고 다음 속성을 넣으세요:

Properties

spring.liquibase.change-log=classpath:/db/changelog/db.changelog-test.yaml

YAML

spring:
  liquibase:
    change-log: "classpath:/db/changelog/db.changelog-test.yaml"

이렇게 하면 테스트를 실행할 때 Liquibase가 다른 변경 로그를 사용하도록 구성됩니다.

이제 src/test/resources/db/changelog/db.changelog-test.yaml에서 프로덕션 변경 로그를 포함하고 테스트별 변경 세트를 추가해야 합니다:

databaseChangeLog:
  - include:
      file: db/changelog/db.changelog-master.yaml
  - changeSet:
      id: test-data
      author: test
      changes:
        - insert:
            tableName: my_table
            columns:
              - column:
                  name: id
                  value: 1
              - column:
                  name: name
                  value: test

이제 테스트를 실행하면 프로덕션 변경 로그가 먼저 실행된 다음 테스트별 변경 세트가 실행됩니다.

Depend Upon an Initialized Database

데이터베이스 초기화는 애플리케이션 시작 중에 수행됩니다. 시작 시 초기화된 데이터베이스에 액세스하려면 데이터베이스 이니셜라이저 역할을 하는 빈과 데이터베이스 초기화가 필요한 빈을 감지하는 것이 중요합니다. 이 섹션에서는 Spring Boot에서 사용하는 감지 메커니즘과 이를 구성하는 방법을 설명합니다.

Detect a Database Initializer

Spring Boot는 다음 유형의 빈을 데이터베이스 이니셜라이저로 자동 감지합니다:

  • DataSourceScriptDatabaseInitializer
  • EntityManagerFactory
  • Flyway
  • FlywayMigrationInitializer
  • R2dbcScriptDatabaseInitializer
  • SpringLiquibase

사용자 정의 데이터베이스 이니셜라이저 빈을 사용하는 경우 @DependsOnDatabaseInitialization으로 어노테이션을 달아야 합니다. 그러면 다른 빈이 의존할 수 있도록 데이터베이스 이니셜라이저로 감지됩니다. 또는 기본 구성 클래스에서 DatabaseInitializationDependencyConfigurer의 서브클래스를 선언하고 감지할 데이터베이스 이니셜라이저 빈 유형으로 어노테이션을 달 수 있습니다. 예를 들어 사용자 정의 DataSourceInitializer 빈을 사용하는 경우 다음과 같이 등록할 수 있습니다:

@Configuration(proxyBeanMethods = false)
@DependsOnDatabaseInitialization(DataSourceInitializer.class)
static class DataSourceInitializerDetectionConfiguration
    extends DatabaseInitializationDependencyConfigurer {

}

Detect a Bean That Depends On Database Initialization

Spring Boot는 다음 유형의 빈을 데이터베이스 초기화에 의존하는 것으로 자동 감지합니다:

  • JdbcOperations
  • NamedParameterJdbcOperations

사용자 정의 빈 유형을 사용하는 경우 @DependsOnDatabaseInitialization으로 어노테이션을 달아야 합니다. 또는 기본 구성 클래스에서 DatabaseInitializationDependencyConfigurer의 서브클래스를 선언하고 데이터베이스 초기화에 의존하는 빈 유형으로 어노테이션을 달 수 있습니다.

반응형
  • 네이버 블로그 공유
  • 네이버 밴드 공유
  • 페이스북 공유
  • 카카오스토리 공유