1. 개요
Spring Boot를 사용하면 데이터베이스 변경 사항을 쉽게 관리 할 수 있습니다. 기본 구성을 그대로두면 패키지에서 엔터티를 검색하고 각 테이블을 자동으로 생성합니다.
그러나 때때로 우리는 데이터베이스 변경에 대해 좀 더 세밀한 제어가 필요할 것입니다. 이때 Spring에서 data.sql 및 schema.sql 파일을 사용할 수 있습니다 .
2. data.sql 파일
또한 여기서 JPA로 작업하고 있다고 가정 하고 프로젝트에서 간단한 국가 엔터티를 정의 해 보겠습니다 .
@Entity
public class Country {
@Id
@GeneratedValue(strategy = IDENTITY)
private Integer id;
@Column(nullable = false)
private String name;
//...
}
애플리케이션을 실행하면 Spring Boot는 빈 테이블을 생성하지만 아무것도 채우지 않습니다.
이를 수행하는 쉬운 방법은 data.sql 이라는 파일을 만드는 것입니다 .
INSERT INTO country (name) VALUES ('India');
INSERT INTO country (name) VALUES ('Brazil');
INSERT INTO country (name) VALUES ('USA');
INSERT INTO country (name) VALUES ('Italy');
클래스 경로에서이 파일을 사용하여 프로젝트를 실행하면 Spring은이를 선택하여 데이터베이스를 채우는 데 사용합니다.
3. schema.sql 파일
때로는 기본 스키마 생성 메커니즘에 의존하고 싶지 않습니다. 이러한 경우 사용자 지정 schema.sql 파일을 만들 수 있습니다 .
CREATE TABLE country (
id INTEGER NOT NULL AUTO_INCREMENT,
name VARCHAR(128) NOT NULL,
PRIMARY KEY (id)
);
Spring은이 파일을 선택하여 스키마 생성에 사용합니다.
충돌을 피하기 위해 자동 스키마 생성을 해제하는 것도 중요합니다.
spring.jpa.hibernate.ddl-auto=none
4. Hibernate를 사용하여 데이터베이스 생성 제어
Spring은 Hibernate가 DDL 생성을 위해 사용 하는 JPA 특정 속성을 제공합니다 : spring.jpa.hibernate.ddl-auto .
표준 Hibernate 속성 값은 create , update , create-drop , validate 및 none입니다 .
- create – Hibernate는 먼저 기존 테이블을 삭제 한 다음 새 테이블을 생성합니다.
- update – 매핑 (어노테이션 또는 XML)을 기반으로 생성 된 객체 모델을 기존 스키마와 비교 한 다음 Hibernate가 diff에 따라 스키마를 업데이트합니다. 응용 프로그램에서 더 이상 필요하지 않더라도 기존 테이블 또는 열을 삭제하지 않습니다.
- create-drop – create 와 유사하며 모든 작업이 완료된 후 Hibernate가 데이터베이스를 삭제한다는 추가 사항이 있습니다. 일반적으로 단위 테스트에 사용
- validate – Hibernate는 테이블과 열이 존재하는지 여부 만 확인합니다. 그렇지 않으면 예외가 발생합니다.
- 없음 –이 값은 DDL 생성을 효과적으로 해제합니다.
Spring Boot 는 스키마 관리자가 감지되지 않은 경우 내부적으로이 매개 변수 값을 create-drop으로 기본 설정하고 , 그렇지 않은 경우 다른 모든 경우에는 없음 을 기본값으로 설정합니다 .
값을 신중하게 설정하거나 다른 메커니즘 중 하나를 사용하여 데이터베이스를 초기화해야합니다.
5. @Sql
Spring은 또한 우리의 테스트 스키마를 초기화하고 채우는 선언적인 방법 인 @Sql 어노테이션을 제공합니다 .
@Sql 어노테이션을 사용하여 새 테이블을 만들고 통합 테스트를 위해 초기 데이터가있는 테이블을로드하는 방법을 살펴 보겠습니다 .
@Sql({"/employees_schema.sql", "/import_employees.sql"})
public class SpringBootInitialLoadIntegrationTest {
@Autowired
private EmployeeRepository employeeRepository;
@Test
public void testLoadDataForTestClass() {
assertEquals(3, employeeRepository.findAll().size());
}
}
@Sql 어노테이션 의 속성은 다음 과 같습니다.
- config – SQL 스크립트에 대한 로컬 구성입니다. 다음 섹션에서 이에 대해 자세히 설명합니다.
- executionPhase – BEFORE_TEST_METHOD 또는 AFTER_TEST_METHOD 중 스크립트를 실행할시기를 지정할 수도 있습니다.
- 문 – 실행할 인라인 SQL 문을 선언 할 수 있습니다.
- 스크립트 – 실행할 SQL 스크립트 파일의 경로를 선언 할 수 있습니다. 값 속성 의 별칭입니다.
@Sql의 어노테이션은 클래스 레벨 또는 메소드 레벨에서 사용할 수 있습니다 . 해당 메소드에 어노테이션을 달아 특정 테스트 케이스에 필요한 추가 데이터를로드 할 수 있습니다.
@Test
@Sql({"/import_senior_employees.sql"})
public void testLoadDataForTestCase() {
assertEquals(5, employeeRepository.findAll().size());
}
6. @SqlConfig
@SqlConfig 어노테이션 을 사용하여 SQL 스크립트 를 구문 분석하고 실행하는 방법을 구성 할 수 있습니다 .
@SqlConfig 는 전역 구성 역할을하는 클래스 수준에서 선언 할 수 있습니다. 또는 특정 @Sql 어노테이션 을 구성하는 데 사용할 수 있습니다 .
SQL 스크립트의 인코딩과 스크립트 실행을위한 트랜잭션 모드를 지정하는 예를 살펴 보겠습니다.
@Test
@Sql(scripts = {"/import_senior_employees.sql"},
config = @SqlConfig(encoding = "utf-8", transactionMode = TransactionMode.ISOLATED))
public void testLoadDataForTestCase() {
assertEquals(5, employeeRepository.findAll().size());
}
@SqlConfig 의 다양한 속성을 살펴 보겠습니다 .
- blockCommentStartDelimiter – SQL 스크립트 파일에서 블록 어노테이션의 시작을 식별하는 구분 기호
- blockCommentEndDelimiter – SQL 스크립트 파일에서 블록 어노테이션의 끝을 나타내는 구분 기호
- commentPrefix – SQL 스크립트 파일에서 한 줄 어노테이션을 식별하기위한 접두사
- dataSource – 스크립트 및 명령문이 실행될 javax.sql.DataSource Bean의 이름
- encoding – SQL 스크립트 파일의 인코딩, 기본값은 플랫폼 인코딩입니다.
- errorMode – 스크립트 실행 중 오류가 발생했을 때 사용되는 모드
- separator – 개별 명령문을 구분하는 데 사용되는 문자열, 기본값은 "–"입니다.
- transactionManager – 트랜잭션에 사용될 PlatformTransactionManager 의 빈 이름
- transactionMode – 트랜잭션 에서 스크립트를 실행할 때 사용되는 모드
7. @SqlGroup
Java 8 이상에서는 반복되는 어노테이션을 사용할 수 있습니다. 이 기능은 @Sql 어노테이션에도 사용할 수 있습니다 . Java 7 이하의 경우 컨테이너 어노테이션 — @SqlGroup이 있습니다. @SqlGroup 어노테이션을 사용하여 여러 @Sql 어노테이션을 선언 할 수 있습니다 .
@SqlGroup({
@Sql(scripts = "/employees_schema.sql",
config = @SqlConfig(transactionMode = TransactionMode.ISOLATED)),
@Sql("/import_employees.sql")})
public class SpringBootSqlGroupAnnotationIntegrationTest {
@Autowired
private EmployeeRepository employeeRepository;
@Test
public void testLoadDataForTestCase() {
assertEquals(3, employeeRepository.findAll().size());
}
}
8. 결론
이 빠른 기사에서는 초기 스키마를 설정하고 데이터로 채우기 위해 schema.sql 및 data.sql 파일을 활용 하는 방법을 살펴 보았습니다 . 또한 @Sql, @SqlConfig 및 @SqlGroup 어노테이션을 사용하여 테스트 용 테스트 데이터를로드 하는 방법도 살펴 보았습니다 .
이 접근 방식은 기본적이고 간단한 시나리오에 더 적합하며, 모든 고급 데이터베이스 처리에는 Liquibase 또는 Flyway 와 같은보다 고급적이고 세련된 도구가 필요합니다 .
항상 그렇듯이 코드 조각 은 GitHub 에서 찾을 수 있습니다 .