이번글은 공식 문서에서 소개하는 Embedded Database Support에 대해 정리했습니다.
org.springframework.jdbc.datasource.embedded 패키지는 자바 임베디드(내장형) 데이터베이스 엔진에 대한 지원을 제공합니다.
HSQL, H2, Derby에 대한 지원은 기본적으로 제공됩니다.
또한, 새로운 임베디드 데이터베이스 유형과 DataSource 구현을 연결할 수 있도록 확장 가능한 API도 제공합니다.
Why Use an Embedded Database?
An embedded database can be useful during the development phase of a project because of its lightweight nature. Benefits include ease of configuration, quick startup time, testability, and the ability to rapidly evolve your SQL during development.
임베디드 데이터베이스는 그 가벼운 특성 때문에 프로젝트의 개발 단계 동안 유용할 수 있습니다.
장점으로는 설정의 용이함, 빠른 시작 시간, 테스트 용이성, 그리고 개발 중 SQL을 빠르게 발전시킬 수 있는 능력이 포함됩니다.
Creating an Embedded Database
You can expose an embedded database instance as a bean as the following example shows:
아래 예시와 같이, 임베디드 데이터베이스 인스턴스를 하나의 빈(Bean)으로 등록할 수 있습니다:
@Bean
DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(EmbeddedDatabaseType.H2)
.addScripts("schema.sql", "test-data.sql")
.build();
}
The preceding configuration creates an embedded H2 database that is populated with SQL from the schema.sql and test-data.sql resources in the root of the classpath. In addition, as a best practice, the embedded database is assigned a uniquely generated name. The embedded database is made available to the Spring container as a bean of type javax.sql.DataSource that can then be injected into data access objects as needed.
앞서 나온 설정은 클래스패스(classpath) 루트에 위치한 schema.sql과 test-data.sql 리소스로부터 SQL을 불러와 채워지는 내장형 H2 데이터베이스를 생성합니다. 또한, 모범 사례(Best Practice)로서, 내장형 데이터베이스에는 고유하게 생성된 이름이 할당됩니다.
이 내장형 데이터베이스는 javax.sql.DataSource 타입의 빈(Bean)으로 Spring 컨테이너에 제공되며, 필요에 따라 데이터 접근 객체(data access object)에 주입될 수 있습니다.
Selecting the Embedded Database Type
This section covers how to select one of the three embedded databases that Spring supports. It includes the following topics:
이 섹션은 Spring이 지원하는 세 가지 내장형 데이터베이스 중 하나를 선택하는 방법을 다룹니다.
다음 주제를 포함합니다:
- HSQL 사용하기
- H2 사용하기
- Derby 사용하기
Using HSQL
Spring supports HSQL 1.8.0 and above. HSQL is the default embedded database if no type is explicitly specified. To specify HSQL explicitly, set the type attribute of the embedded-database tag to HSQL. If you use the builder API, call the setType(EmbeddedDatabaseType) method with EmbeddedDatabaseType.HSQL.
Spring은 HSQL 1.8.0 이상을 지원합니다. HSQL은 타입이 명시적으로 지정되지 않은 경우 기본 내장형 데이터베이스입니다. HSQL을 명시적으로 지정하려면 embedded-database 태그의 type 속성을 HSQL로 설정하면 됩니다. 빌더 API를 사용하는 경우, setType(EmbeddedDatabaseType) 메서드를 EmbeddedDatabaseType.HSQL과 함께 호출하면 됩니다.
Using H2
Spring supports the H2 database. To enable H2, set the type attribute of the embedded-database tag to H2. If you use the builder API, call the setType(EmbeddedDatabaseType) method with EmbeddedDatabaseType.H2.
H2 사용하기
Spring은 H2 데이터베이스를 지원합니다. H2를 사용하려면 embedded-database 태그의 type 속성을 H2로 설정하면 됩니다. 빌더 API를 사용하는 경우, setType(EmbeddedDatabaseType) 메서드를 EmbeddedDatabaseType.H2와 함께 호출합니다.
Using Derby
Spring supports Apache Derby 10.5 and above. To enable Derby, set the type attribute of the embedded-database tag to DERBY. If you use the builder API, call the setType(EmbeddedDatabaseType) method with EmbeddedDatabaseType.DERBY.
Derby 사용하기
Spring은 Apache Derby 10.5 버전 이상을 지원합니다. Derby를 사용하려면 embedded-database 태그의 type 속성을 DERBY로 설정하면 됩니다. 빌더 API를 사용하는 경우, setType(EmbeddedDatabaseType) 메서드를 EmbeddedDatabaseType.DERBY와 함께 호출하세요.
Customizing the Embedded Database Type
While each supported type comes with default connection settings, it is possible to customize them if necessary. The following example uses H2 with a custom driver:
내장 데이터베이스 타입 사용자 정의하기
각 지원되는 타입은 기본 연결 설정을 가지고 있지만, 필요하다면 이를 사용자 정의할 수 있습니다. 다음 예제는 사용자 지정 드라이버를 사용하여 H2를 사용하는 방법을 보여줍니다.
@Configuration
public class DataSourceConfig {
@Bean
public DataSource dataSource() {
return new EmbeddedDatabaseBuilder()
.setDatabaseConfigurer(EmbeddedDatabaseConfigurers
.customizeConfigurer(H2, this::customize))
.addScript("schema.sql")
.build();
}
private EmbeddedDatabaseConfigurer customize(EmbeddedDatabaseConfigurer defaultConfigurer) {
return new EmbeddedDatabaseConfigurerDelegate(defaultConfigurer) {
@Override
public void configureConnectionProperties(ConnectionProperties properties, String databaseName) {
super.configureConnectionProperties(properties, databaseName);
properties.setDriverClass(CustomDriver.class);
}
};
}
}
Testing Data Access Logic with an Embedded Database
Embedded databases provide a lightweight way to test data access code. The next example is a data access integration test template that uses an embedded database. Using such a template can be useful for one-offs when the embedded database does not need to be reused across test classes. However, if you wish to create an embedded database that is shared within a test suite, consider using the Spring TestContext Framework and configuring the embedded database as a bean in the Spring ApplicationContext as described in Creating an Embedded Database. The following listing shows the test template:
내장 데이터베이스는 데이터 접근 코드를 테스트할 수 있는 가벼운 방법을 제공합니다. 다음 예제는 내장 데이터베이스를 사용하는 데이터 접근 통합 테스트 템플릿입니다. 이러한 템플릿은 테스트 클래스 간에 내장 데이터베이스를 재사용할 필요가 없을 때 일회성으로 유용하게 사용할 수 있습니다. 하지만 테스트 모음 내에서 공유되는 내장 데이터베이스를 만들고자 한다면, Creating an Embedded Database에서 설명한 것처럼 Spring TestContext Framework를 사용하고, 내장 데이터베이스를 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();
}
}
Generating Unique Names for Embedded Databases
Development teams often encounter errors with embedded databases if their test suite inadvertently attempts to recreate additional instances of the same database. This can happen quite easily if an XML configuration file or @Configuration class is responsible for creating an embedded database and the corresponding configuration is then reused across multiple testing scenarios within the same test suite (that is, within the same JVM process) — for example, integration tests against embedded databases whose ApplicationContext configuration differs only with regard to which bean definition profiles are active.
개발 팀은 종종 내장 데이터베이스를 사용할 때 오류를 겪는데, 이는 테스트 모음이 동일한 데이터베이스의 인스턴스를 실수로 추가로 생성하려고 할 때 발생합니다. 이러한 상황은 XML 설정 파일이나 @Configuration 클래스가 내장 데이터베이스를 생성하는 역할을 하고, 해당 설정이 동일한 테스트 모음(즉, 동일한 JVM 프로세스 내)에서 여러 테스트 시나리오에서 재사용될 경우 쉽게 발생할 수 있습니다. 예를 들어, 빈 정의 프로파일이 활성화된 것만 다르고 나머지 설정은 동일한 ApplicationContext 구성을 사용하는 내장 데이터베이스에 대한 통합 테스트에서 이런 일이 일어날 수 있습니다.
The root cause of such errors is the fact that Spring’s EmbeddedDatabaseFactory (used internally by both the <jdbc:embedded-database> XML namespace element and the EmbeddedDatabaseBuilder for Java configuration) sets the name of the embedded database to testdb if not otherwise specified. For the case of <jdbc:embedded-database>, the embedded database is typically assigned a name equal to the bean’s id (often, something like dataSource). Thus, subsequent attempts to create an embedded database do not result in a new database. Instead, the same JDBC connection URL is reused, and attempts to create a new embedded database actually point to an existing embedded database created from the same configuration.
이러한 오류의 근본 원인은, Spring의 EmbeddedDatabaseFactory가 (이 클래스는 <jdbc:embedded-database> XML 네임스페이스 요소와 Java 설정에서 사용하는 EmbeddedDatabaseBuilder 모두 내부적으로 사용함) embedded database의 이름을 별도로 지정하지 않으면 testdb로 설정한다는 사실에 있습니다.
<jdbc:embedded-database>의 경우, embedded database는 일반적으로 해당 bean의 id (예: dataSource)와 같은 이름으로 할당됩니다. 그 결과, embedded database를 새로 생성하려는 시도가 실제로는 새로운 DB를 생성하는 것이 아니라, 이전에 동일한 설정으로 생성된 DB와 동일한 JDBC 연결 URL을 재사용하게 됩니다. 즉, 새로운 embedded database를 만들려는 시도는 실제로는 기존에 이미 생성된 embedded database를 가리키게 되는 것입니다.
To address this common issue, Spring Framework 4.2 provides support for generating unique names for embedded databases. To enable the use of generated names, use one of the following options.
- EmbeddedDatabaseFactory.setGenerateUniqueDatabaseName()
- EmbeddedDatabaseBuilder.generateUniqueName()
- <jdbc:embedded-database generate-name="true" … >
이 일반적인 문제를 해결하기 위해, Spring Framework 4.2는 내장 데이터베이스에 대해 고유한 이름을 생성하는 기능을 지원합니다.
고유한 이름 생성을 활성화하려면, 아래 옵션들 중 하나를 사용하면 됩니다:
- EmbeddedDatabaseFactory.setGenerateUniqueDatabaseName()
- EmbeddedDatabaseBuilder.generateUniqueName()
- <jdbc:embedded-database generate-name="true" … >
즉, 위의 방법들을 사용하면 Spring이 자동으로 중복되지 않는 데이터베이스 이름을 생성해서, 테스트 간 DB 충돌을 방지할 수 있다는 의미입니다.
Extending the Embedded Database Support
You can extend Spring JDBC embedded database support in two ways:
- Implement EmbeddedDatabaseConfigurer to support a new embedded database type.
- Implement DataSourceFactory to support a new DataSource implementation, such as a connection pool to manage embedded database connections.
Spring JDBC의 내장 데이터베이스 지원은 두 가지 방법으로 확장할 수 있습니다:
- EmbeddedDatabaseConfigurer를 구현하여 새로운 내장 데이터베이스 유형을 지원할 수 있습니다.
- DataSourceFactory를 구현하여, 내장 데이터베이스 연결을 관리하는 커넥션 풀 같은 새로운 DataSource 구현을 지원할 수 있습니다.
'공식문서' 카테고리의 다른 글
[Spring Docs] Data Access with R2DBC (0) | 2025.04.17 |
---|---|
[Spring Docs] Initializing a DataSource (0) | 2025.04.15 |
[Spring Docs] Common Problems with Parameter and Data Value Handling (0) | 2025.04.11 |
[Spring Docs] Modeling JDBC Operations as Java Objects (0) | 2025.04.10 |
[Spring Docs] Simplifying JDBC Operations with the SimpleJdbc Classes (0) | 2025.04.09 |