El paquete org.springframework.jdbc.datasource.embedded
proporciona soporte para motores de
almacenamiento integrados en Java. Soporte HSQL, H2 y Derby se proporcionan de
forma nativa. También puede utilizar la API extensible para conectar nuevos tipos de bases de datos integradas e
implementaciones de DataSource
.
¿Por qué utilizar una base de datos integrada?
Una base de datos integrada puede ser útil en la etapa de desarrollo del proyecto debido a su simplicidad. Los beneficios incluyen facilidad de configuración, tiempo de inicio rápido, capacidad de prueba y la capacidad de refinar rápidamente SQL durante el desarrollo.
Creación de una base de datos integrada utilizando Spring XML
Si necesita exponer una instancia de una base de datos integrada en Como bean en ApplicationContext
en
Spring, puede usar la etiqueta embedded-database
en el espacio de nombres spring-jdbc
:
<jdbc:embedded-database id="dataSource" generate-name="true">
<jdbc:script location="classpath:schema.sql"/>
<jdbc:script location="classpath:test-data.sql"/>
</jdbc:embedded-database>
La configuración anterior crea una base de datos HSQL integrada que se completa con SQL desde recursos de
schema.sql
y test-data.sql
en la raíz del classpath. Además, como práctica recomendada, la
base de datos integrada recibe un nombre único. La base de datos integrada se pone a disposición del contenedor
Spring como un bean de tipo javax.sql.DataSource
, que luego se puede inyectar en objetos de acceso a
datos según sea necesario.
Crear una base de datos integrada base de datos mediante programación
La
clase EmbeddedDatabaseBuilder
proporciona una API gratuita para crear una base de datos integrada
mediante programación. Esto se puede utilizar si necesita crear una base de datos integrada en un entorno
independiente o en una prueba de integración independiente, como en el siguiente ejemplo:
EmbeddedDatabase db = new EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(H2)
.setScriptEncoding("UTF-8")
.ignoreFailedDrops(true)
.addScript("schema.sql")
.addScripts("user_data.sql", "country_data.sql")
.build();
// realiza acciones con la base de datos (EmbeddedDatabase extiende javax.sql.DataSource)
db.shutdown()
val db = EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(H2)
.setScriptEncoding("UTF-8")
.ignoreFailedDrops(true)
.addScript("schema.sql")
.addScripts("user_data.sql", "country_data.sql")
.build()
// realiza acciones en la base de datos (EmbeddedDatabase extiende javax.sql.DataSource)
db.shutdown()
cm. javadoc EmbeddedDatabaseBuilder
para obtener más detalles sobre todas las
opciones admitidas.
También puede utilizar EmbeddedDatabaseBuilder
para crear una base de datos
integrada usando la configuración de Java, como se muestra en el siguiente ejemplo:
@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();
}
}
@Configuration
class DataSourceConfig {
@Bean
fun dataSource(): DataSource {
return EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.setType(H2)
.setScriptEncoding("UTF-8")
.ignoreFailedDrops(true)
.addScript("schema.sql")
.addScripts("user_data.sql", "country_data.sql")
.build()
}
}
Seleccionar un tipo de base de datos integrada
Esta sección explica cómo seleccionar uno de los tres tipos de base de datos integrada. en bases de datos que soporta Spring. La sección incluye los siguientes temas:
Uso de HSQL
Uso de H2
Usando Derby
Uso de HSQL
Spring admite HSQL 1.8.0 y superior. HSQL es la base de datos integrada predeterminada si el tipo no se especifica
explícitamente. Para especificar HSQL explícitamente, establezca el atributo type
de la etiqueta embedded-database
en HSQL
. Si está utilizando la API de la herramienta de compilación, llame al método setType(EmbeddedDatabaseType)
con el parámetro EmbeddedDatabaseType.HSQL
.
Uso de H2
Spring admite la base de
datos H2. Para habilitar H2, establezca el atributo type
de la etiqueta embedded-database
en H2
. Si está utilizando la API de la herramienta de compilación, llame al método setType(EmbeddedDatabaseType)
con el parámetro EmbeddedDatabaseType.H2
.
Uso de Derby
Spring admite Apache
Derby 10.5 y más alto. Para habilitar Derby, establezca el atributo type
de la etiqueta embedded-database
en DERBY
. Si está utilizando la API de la herramienta de compilación, llame al método setType(EmbeddedDatabaseType)
con el parámetro EmbeddedDatabaseType.DERBY
.
Prueba de la lógica de acceso a datos utilizando una base de datos integrada
Las bases de datos integradas proporcionan una forma
sencilla de probar el código para recuperar una muestra de datos. El siguiente ejemplo es una plantilla de prueba de
integración de acceso a datos que utiliza una base de datos integrada. El uso de un patrón de este tipo puede
resultar útil para casos de uso únicos en los que no es necesario reutilizar la base de datos integrada en todas las
clases de prueba. Sin embargo, si necesita crear una base de datos integrada que se compartirá entre el conjunto de
pruebas, utilice Spring TestContext
Framework y configurar la base de datos integrada como un bean en ApplicationContext
de
Spring, como se describe arriba. La siguiente lista muestra el patrón de prueba:
public class DataAccessIntegrationTestTemplate {
private EmbeddedDatabase db;
@BeforeEach
public void setUp() {
// creates an in-memory resident HSQL database filled with 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();
}
}
class DataAccessIntegrationTestTemplate {
private lateinit var db: EmbeddedDatabase
@BeforeEach
fun setUp() {
// creates an in-memory resident HSQL database filled with default scripts
// classpath:schema.sql and classpath:data.sql
db = EmbeddedDatabaseBuilder()
.generateUniqueName(true)
.addDefaultScripts()
.build()
}
@Test
fun testDataAccess() {
val template = JdbcTemplate(db)
template.query( /* ... */)
}
@AfterEach
fun tearDown() {
db.shutdown()
}
}
Creación de nombres únicos para bases de datos integradas
Los equipos de desarrollo a menudo
encuentran errores cuando trabajan con bases de datos integradas si su conjunto de pruebas intenta accidentalmente
recrear instancias adicionales de la misma base de datos. Esto puede suceder con bastante facilidad si un archivo o
clase de configuración XML con la anotación @Configuration
es responsable de crear la base de datos
integrada, y la configuración correspondiente luego se reutiliza en múltiples casos de prueba dentro de un único
conjunto de pruebas (es decir, dentro de un único proceso JVM) - por ejemplo, pruebas de integración contra bases de
datos integradas cuya configuración ApplicationContext
difiere sólo en qué perfiles de definición de
beans están activos.
La causa principal de tales errores es el hecho que la fábrica EmbeddedDatabaseFactory
de Spring (utilizada internamente tanto por el elemento de espacio de nombres XML <jdbc:embedded-database>
como por la configuración EmbeddedDatabaseBuilder
para Java ) establece el nombre de la base de datos
integrada en testdb
a menos que se especifique lo contrario. En el caso de <jdbc:embedded-database>
,
la base de datos integrada normalmente recibe un nombre igual al id
del bean (a menudo algo así como
dataSource
). Por lo tanto, los intentos posteriores de crear la base de datos incorporada no dan
como resultado la creación de una nueva base de datos. En su lugar, se reutiliza la misma URL de conexión JDBC y
los intentos de crear una nueva base de datos integrada en realidad apuntan a una base de datos integrada
existente creada a partir de la misma configuración.
Para resolver este problema común, Spring Framework 4.2 proporciona soporte para generar nombres únicos para bases de datos integradas. Para habilitar la función para usar nombres generados, use uno de los siguientes parámetros.
EmbeddedDatabaseFactory.setGenerateUniqueDatabaseName()
EmbeddedDatabaseBuilder.generateUniqueName()
<jdbc:embedded-database generate-name="true" … >
Ampliación del soporte de bases de datos nativas
Puede ampliar el soporte de bases de datos JDBC nativas de Spring de dos maneras:
Implementando
EmbeddedDatabaseConfigurer
para proporcionar soporte para un nuevo tipo de base de datos integrada.Implementando
DataSourceFactory
para brindar soporte para una nueva implementación deDataSource
, como un grupo de conexiones para administrar las conexiones a la base de datos integrada.
Le recomendamos que Contribuya con sugerencias de extensiones a la comunidad Spring en GitHub Issues.