Loading...
Spring Framework Reference Documentation 7.0.2의 Embedded Database Support의 한국어 번역본입니다.
아래의 경우에 피드백에서 신고해주신다면 반영하겠습니다.
감사합니다 :)
org.springframework.jdbc.datasource.embedded package는 embedded Java database engine을 위한 지원을 제공합니다. HSQL, H2, 그리고 Derby에 대한 지원이 기본적으로 제공됩니다. 또한 확장 가능한 API를 사용하여 새로운 embedded database type과 DataSource implementation을 plug-in 할 수 있습니다.
embedded database는 lightweight 특성 때문에 project의 개발 단계 동안 유용할 수 있습니다. 이점에는 configuration의 용이성, 빠른 startup 시간, testability, 그리고 개발 중에 SQL을 빠르게 발전시킬 수 있는 능력이 포함됩니다.
다음 예제에서 보는 것처럼 embedded database instance를 bean으로 노출할 수 있습니다:
1@Bean 2DataSource dataSource() { 3 return new EmbeddedDatabaseBuilder() 4 .generateUniqueName(true) 5 .setType(EmbeddedDatabaseType.H2) 6 .addScripts("schema.sql", "test-data.sql") 7 .build(); 8}
1@Bean 2fun dataSource() = EmbeddedDatabaseBuilder() 3 .generateUniqueName(true) 4 .setType(EmbeddedDatabaseType.H2) 5 .addScripts("schema.sql", "test-data.sql") 6 .build()
1<jdbc:embedded-database id="dataSource" generate-name="true" type="H2"> 2 <jdbc:script location="classpath:schema.sql"/> 3 <jdbc:script location="classpath:test-data.sql"/> 4</jdbc:embedded-database>
위의 configuration은 classpath root에 있는 schema.sql 및 test-data.sql resource의 SQL로 채워지는 embedded H2 database를 생성합니다. 추가로, best practice로서 embedded database에는 고유하게 생성된 이름이 할당됩니다.
embedded database는 javax.sql.DataSource type의 bean으로 Spring 컨테이너에 제공되며, 필요에 따라 data access 객체에 injection될 수 있습니다.
모든 지원되는 option에 대한 자세한 내용은 EmbeddedDatabaseBuilder에 대한 javadoc을 참조하십시오.
이 section에서는 Spring이 지원하는 세 가지 embedded database 중 하나를 선택하는 방법을 다룹니다. 다음 topic이 포함됩니다:
Spring은 HSQL 1.8.0 이상을 지원합니다. type이 명시적으로 지정되지 않은 경우 HSQL이 기본 embedded database입니다. HSQL을 명시적으로 지정하려면 embedded-database tag의 type attribute를 HSQL로 설정하십시오. builder API를 사용하는 경우 setType(EmbeddedDatabaseType) 메서드를 EmbeddedDatabaseType.HSQL과 함께 호출하십시오.
Spring은 H2 database를 지원합니다. H2를 활성화하려면 embedded-database tag의 type attribute를 H2로 설정하십시오. builder API를 사용하는 경우 setType(EmbeddedDatabaseType) 메서드를 EmbeddedDatabaseType.H2와 함께 호출하십시오.
Spring은 Apache Derby 10.5 이상을 지원합니다. Derby를 활성화하려면 embedded-database tag의 type attribute를 DERBY로 설정하십시오. builder API를 사용하는 경우 setType(EmbeddedDatabaseType) 메서드를 EmbeddedDatabaseType.DERBY와 함께 호출하십시오.
각 지원되는 type은 기본 connection setting을 제공하지만, 필요하다면 이를 customize하는 것이 가능합니다. 다음 예제는 custom driver와 함께 H2를 사용하는 예제입니다:
1@Configuration 2public class DataSourceConfig { 3 4 @Bean 5 public DataSource dataSource() { 6 return new EmbeddedDatabaseBuilder() 7 .setDatabaseConfigurer(EmbeddedDatabaseConfigurers 8 .customizeConfigurer(H2, this::customize)) 9 .addScript("schema.sql") 10 .build(); 11 } 12 13 private EmbeddedDatabaseConfigurer customize(EmbeddedDatabaseConfigurer defaultConfigurer) { 14 return new EmbeddedDatabaseConfigurerDelegate(defaultConfigurer) { 15 @Override 16 public void configureConnectionProperties(ConnectionProperties properties, String databaseName) { 17 super.configureConnectionProperties(properties, databaseName); 18 properties.setDriverClass(CustomDriver.class); 19 } 20 }; 21 } 22}
1@Configuration 2class DataSourceConfig { 3 4 @Bean 5 fun dataSource(): DataSource { 6 return EmbeddedDatabaseBuilder() 7 .setDatabaseConfigurer(EmbeddedDatabaseConfigurers 8 .customizeConfigurer(EmbeddedDatabaseType.H2) { this.customize(it) }) 9 .addScript("schema.sql") 10 .build() 11 } 12 13 private fun customize(defaultConfigurer: EmbeddedDatabaseConfigurer): EmbeddedDatabaseConfigurer { 14 return object : EmbeddedDatabaseConfigurerDelegate(defaultConfigurer) { 15 override fun configureConnectionProperties( 16 properties: ConnectionProperties, 17 databaseName: String 18 ) { 19 super.configureConnectionProperties(properties, databaseName) 20 properties.setDriverClass(CustomDriver::class.java) 21 } 22 } 23 } 24}
embedded database는 data access 코드을 test하는 lightweight한 방법을 제공합니다. 다음 예제는 embedded database를 사용하는 data access integration test template입니다. 이러한 template을 사용하는 것은 embedded database를 test class 간에 재사용할 필요가 없을 때 one-off에 유용할 수 있습니다.
그러나 test suite 내에서 공유되는 embedded database를 생성하고자 한다면, Spring TestContext Framework를 사용하고 Creating an Embedded Database에 설명된 대로 embedded database를 Spring ApplicationContext 내의 bean으로 configuration하는 것을 고려하십시오. 다음 listing은 test template을 보여줍니다:
1public class DataAccessIntegrationTestTemplate { 2 3 private EmbeddedDatabase db; 4 5 @BeforeEach 6 public void setUp() { 7 // creates an HSQL in-memory database populated from default scripts 8 // classpath:schema.sql and classpath:data.sql 9 db = new EmbeddedDatabaseBuilder() 10 .generateUniqueName(true) 11 .addDefaultScripts() 12 .build(); 13 } 14 15 @Test 16 public void testDataAccess() { 17 JdbcTemplate template = new JdbcTemplate(db); 18 template.query( /* ... */ ); 19 } 20 21 @AfterEach 22 public void tearDown() { 23 db.shutdown(); 24 } 25 26}
1class DataAccessIntegrationTestTemplate { 2 3 private lateinit var db: EmbeddedDatabase 4 5 @BeforeEach 6 fun setUp() { 7 // creates an HSQL in-memory database populated from default scripts 8 // classpath:schema.sql and classpath:data.sql 9 db = EmbeddedDatabaseBuilder() 10 .generateUniqueName(true) 11 .addDefaultScripts() 12 .build() 13 } 14 15 @Test 16 fun testDataAccess() { 17 val template = JdbcTemplate(db) 18 template.query( /* ... */) 19 } 20 21 @AfterEach 22 fun tearDown() { 23 db.shutdown() 24 } 25}
개발 team은 test suite가 실수로 동일한 database의 추가 instance를 재생성하려고 시도할 경우 embedded database에서 error를 자주 겪게 됩니다. 이는 XML configuration file 또는 @Configuration class가 embedded database 생성을 담당하고 해당 configuration이 동일한 test suite(즉, 동일한 JVM process) 내의 여러 testing scenario에서 재사용될 때 매우 쉽게 발생할 수 있습니다.
예를 들어, embedded database에 대한 integration test에서 ApplicationContext configuration이 활성화된 bean definition profile과 관련해서만 다른 경우가 이에 해당합니다.
이러한 error의 근본 원인은 Spring의 EmbeddedDatabaseFactory가 (<jdbc:embedded-database> XML namespace element와 Java configuration을 위한 EmbeddedDatabaseBuilder 모두에서 내부적으로 사용됨) 별도로 지정되지 않은 경우 embedded database의 이름을 testdb로 설정한다는 사실입니다. <jdbc:embedded-database>의 경우 embedded database에는 일반적으로 bean의 id(종종 dataSource와 같은 것)와 동일한 이름이 할당됩니다.
따라서 embedded database를 생성하려는 이후의 시도는 새로운 database를 생성하지 않습니다. 대신 동일한 JDBC connection URL이 재사용되며, 새로운 embedded database를 생성하려는 시도는 실제로 동일한 configuration에서 생성된 기존 embedded database를 가리키게 됩니다.
이 일반적인 문제를 해결하기 위해 Spring Framework 4.2는 embedded database를 위한 고유한 이름 생성을 지원합니다. 생성된 이름의 사용을 활성화하려면 다음 option 중 하나를 사용하십시오.
EmbeddedDatabaseFactory.setGenerateUniqueDatabaseName()EmbeddedDatabaseBuilder.generateUniqueName()<jdbc:embedded-database generate-name="true" … >Spring JDBC embedded database 지원은 두 가지 방식으로 확장할 수 있습니다:
EmbeddedDatabaseConfigurer를 구현합니다.DataSource implementation을 지원하기 위해 DataSourceFactory를 구현합니다.Spring community에 extension을 GitHub Issues에 contribute해 주시기 바랍니다.
Common Problems with Parameter and Data Value Handling
Initializing a DataSource