org.springframework.jdbc.datasource.embedded 패키지는 임베디드 Java 데이터베이스 엔진에 대한 지원을 제공합니다. HSQL, H2 및 Derby에 대한 지원이 기본적으로 제공됩니다. 또한 확장 가능한 API를 사용하여 새로운 내장형 데이터베이스 타입 및 DataSource 구현을 연결할 수도 있습니다.
내장된 데이터베이스는 가벼운 특성으로 인해 프로젝트 개발 단계에서 유용할 수 있습니다. 이점에는 구성 용이성, 빠른 시작 시간, 테스트 가능성, 개발 중에 SQL을 빠르게 발전시킬 수 있는 기능이 포함됩니다.
Spring ApplicationContext에서 내장된 데이터베이스 인스턴스를 빈으로 노출하려면 spring-jdbc 네임스페이스에서 embedded-database 태그를 사용할 수 있습니다.
<jdbc:embedded-database id="dataSource" generate-name="true">
<jdbc:script location="classpath:schema.sql"/>
<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>
이전 구성은 classpath 루트에 있는 schema.sql 및 test-data.sql 리소스의 SQL로 채워지는 임베디드 HSQL 데이터베이스를 생성합니다. 또한 모범 사례에 따라 내장된 데이터베이스에는 고유하게 생성된 이름이 할당됩니다. 내장된 데이터베이스는 필요에 따라 데이터 액세스 객체에 주입될 수 있는 javax.sql.DataSource 유형의 Bean으로 Spring 컨테이너에서 사용할 수 있습니다.
EmbeddedDatabaseBuilder 클래스는 프로그래밍 방식으로 임베디드 데이터베이스를 구성하기 위한 원활한 API를 제공합니다. 다음 예와 같이 독립형 환경이나 독립형 통합 테스트에서 임베디드 데이터베이스를 생성해야 할 때 이를 사용할 수 있습니다.
EmbeddedDatabase db = new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(H2)
.setScriptEncoding("UTF-8")
.ignoreFailedDrops(true)
.addScript("schema.sql")
.addScripts("user_data.sql", "country_data.sql")
.build();
// perform actions against the db (EmbeddedDatabase extends javax.sql.DataSource)
db.shutdown()
지원되는 모든 옵션에 대한 자세한 내용은 EmbeddedDatabaseBuilder에 대한 javadoc를 참조하세요. 다음 예제와 같이 EmbeddedDatabaseBuilder를 사용하여 Java 구성을 사용하여 내장형 데이터베이스를 생성할 수도 있습니다.
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(H2)
.setScriptEncoding("UTF-8")
.ignoreFailedDrops(true)
.addScript("schema.sql")
.addScripts("user_data.sql", "country_data.sql")
.build();
}
}
이 섹션에서는 Spring이 지원하는 세 가지 내장 데이터베이스 중 하나를 선택하는 방법을 다룹니다. 여기에는 다음 주제가 포함됩니다.
Spring은 HSQL 1.8.0 이상을 지원합니다. 타입이 명시적으로 지정되지 않은 경우 HSQL은 기본 내장 데이터베이스입니다. HSQL을 명시적으로 지정하려면 embedded-database 태그의 type 속성(attribute)을 HSQL로 설정하십시오. 빌더 API를 사용하는 경우 EmbeddedDatabaseType.HSQL을 사용하여 setType(EmbeddedDatabaseType) 메서드를 호출하세요.
Spring은 H2 데이터베이스를 지원합니다. H2를 활성화하려면 embedded-database 태그의 type 속성(attribute)을 H2로 설정하십시오. 빌더 API를 사용하는 경우 EmbeddedDatabaseType.H2와 함께 setType(EmbeddedDatabaseType) 메서드를 호출하세요.
Spring은 Apache Derby 10.5 이상을 지원합니다. Derby를 활성화하려면 embedded-database 태그의 type 속성을 DERBY로 설정하십시오. 빌더 API를 사용하는 경우 EmbeddedDatabaseType.DERBY를 사용하여 setType(EmbeddedDatabaseType) 메서드를 호출하세요.
내장된 데이터베이스는 데이터 액세스 코드를 테스트하는 간단한 방법을 제공합니다. 다음 예는 내장된 데이터베이스를 사용하는 데이터 액세스 통합 테스트 템플릿입니다. 이러한 템플릿을 사용하면 내장된 데이터베이스를 테스트 클래스 전체에서 재사용할 필요가 없을 때 일회용(one-offs)으로 유용할 수 있습니다. 그러나 테스트 스위트 내에서 공유되는 임베디드 데이터베이스를 생성하려는 경우 Spring TestContext Framework를 사용하고 Spring XML을 사용하여 임베디드 데이터베이스 생성, 프로그래밍 방식으로 임베디드 데이터베이스 생성에 설명된 대로 Spring ApplicationContext에서 임베디드 데이터베이스를 빈으로 구성하는 것을 고려하십시오. 다음 목록은 테스트 템플릿을 보여줍니다.
public class DataAccessIntegrationTestTemplate {
private EmbeddedDatabase db;
@BeforeEach
public void setUp() {
// creates an HSQL in-memory database populated from default scripts
// classpath:schema.sql and classpath:data.sql
db = new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.addDefaultScripts()
.build();
}
@Test
public void testDataAccess() {
JdbcTemplate template = new JdbcTemplate(db);
template.query( /* ... */ );
}
@AfterEach
public void tearDown() {
db.shutdown();
}
}
개발 팀은 테스트 스위트가 실수로 동일한 데이터베이스의 추가 인스턴스를 다시 생성하려고 시도하는 경우 내장된 데이터베이스에 오류가 발생하는 경우가 많습니다. XML 구성 파일 또는 @Configuration 클래스가 내장된 데이터베이스 생성을 담당하고 해당 구성이 동일한 테스트 스위트(즉, 동일한 JVM 프로세스 내) 내의 여러 테스트 시나리오에서 재사용되는 경우 매우 쉽게 발생할 수 있습니다. 예를 들어, 활성화된 Bean 정의 프로파일에 대해서만 ApplicationContext 구성이 다른 내장된 데이터베이스에 대한 통합 테스트같은 경우입니다.
이러한 오류의 근본 원인은 Spring의 EmbeddedDatabaseFactory(<jdbc:embedded-database> XML 네임스페이스 요소와 Java 구성용 EmbeddedDatabaseBuilder 모두에서 내부적으로 사용됨)가 달리 지정되지 않은 경우 내장 데이터베이스의 이름을 testdb로 설정한다는 사실입니다. <jdbc:embedded-database>의 경우 내장된 데이터베이스에는 일반적으로 Bean의 id와 동일한 이름(종종 dataSource와 같은 이름)이 할당됩니다. 따라서 이후에 내장형 데이터베이스를 생성하려고 시도해도 새 데이터베이스가 생성되지 않습니다. 대신, 동일한 JDBC 연결 URL이 재사용되며, 새로운 내장 데이터베이스를 생성하려는 시도는 실제로 동일한 구성에서 생성된 기존 내장 데이터베이스를 가리킵니다.
이 일반적인 문제를 해결하기 위해 Spring Framework 4.2는 임베디드 데이터베이스에 대한 고유 이름 생성을 지원합니다. 생성된 이름을 사용하려면 다음 옵션 중 하나를 사용하십시오.
EmbeddedDatabaseFactory.setGenerateUniqueDatabaseName()
EmbeddedDatabaseBuilder.generateUniqueName()
<jdbc:embedded-database generate-name="true" … >
두 가지 방법으로 Spring JDBC 임베디드 데이터베이스 지원을 확장할 수 있습니다.
새로운 임베디드 데이터베이스 타입을 지원하려면 EmbeddedDatabaseConfigurer를 구현하십시오.
내장된 데이터베이스 연결을 관리하기 위한 connection 풀과 같은 새로운 DataSource 구현을 지원하려면 DataSourceFactory를 구현하십시오.
GitHub Issues에서 Spring 커뮤니티에 확장 기능을 제공하는 것이 좋습니다.