2013-04-16 12 views
39

Vorrei sapere come inizializzare un database senza dover creare un file XML.Inizializzazione del database senza configurazione XML, ma utilizzando @Configuration

ho già utilizzare questo tipo di inizializzazione che funziona bene, ma nel mio caso attuale io non voglio creare un XML:

<jdbc:initialize-database data-source="dataSource"> 
    <jdbc:script location="classpath:com/foo/sql/db-schema.sql"/> 
    <jdbc:script location="classpath:com/foo/sql/db-test-data.sql"/> 
</jdbc:initialize-database> 

So di poter creare un database embedded con:

EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); 
EmbeddedDatabase db = builder.setType(H2).addScript("my-schema.sql").addScript("my-test-data.sql").build(); 

Nel mio caso, il database e lo schema vengono creati utilizzando Liquibase.

Voglio solo inizializzarlo con Spring e con il mio set di dati personalizzato, senza dover creare un nuovo file XML ogni volta solo per quello.

È possibile?

risposta

6

Dopo aver guardato le classi primavera relative alla EmbeddedDatabaseBuilder ho scoperto che la DatabaseBuilder sta usando un codice simile a questo:

ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); 
for (String sqlScript: sqlInitializationScripts) { 
    Resource sqlScriptResource = RESOURCE_LOADER.getResource(sqlScript); 
    populator.addScript(sqlScriptResource); 
} 
DatabasePopulatorUtils.execute(populator, dataSource); 

Questo funziona bene per me, anche se sarà una Metodo @BeforeTest e non sulla configurazione Spring.

+0

Funziona. Utilizzare new ClassPathResource (sqlScript) per ottenere la risorsa. – Dayong

+0

Sembra che tu abbia cambiato la tua domanda. Questa risposta non sembra correlata alla domanda secondo me. La prima risposta ha più senso. – Behrang

6

È certamente possibile.

Se si dispone già di una classe @Configuration che viene caricata entro la primavera del ApplicationContext, allora devi semplicemente creare un nuovo metodo di @Bean che conterrà il codice che c'è già (con un ulteriore return dichiarazione ovviamente).

EmbeddedDatabase implementa l'interfaccia DataSource, quindi può essere facilmente utilizzata con JdbcTemplate.

@Bean 
public DataSource db() { 
    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); 
    builder.setType(H2).addScript("my-schema.sql").addScript("my-test-data.sql"); 
    return builder.build(); 
} 
+0

No, non è così, non voglio creare un nuovo DataSource: ne ho già uno! –

+0

Bene, allora puoi cambiare il tipo di ritorno come 'EmbeddedDatabase' se vuoi, dato che un' EmbeddedDatabase' è un 'DataSource'. Tutto quello che sto suggerendo qui è che puoi usare 'DataSource' facilmente con' JdbcTemplate'. –

31

Le seguenti righe di codice all'interno della classe @Configuration potrebbero funzionare.

@Value("classpath:com/foo/sql/db-schema.sql") 
private Resource schemaScript; 

@Value("classpath:com/foo/sql/db-test-data.sql") 
private Resource dataScript; 

@Bean 
public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) { 
    final DataSourceInitializer initializer = new DataSourceInitializer(); 
    initializer.setDataSource(dataSource); 
    initializer.setDatabasePopulator(databasePopulator()); 
    return initializer; 
} 

private DatabasePopulator databasePopulator() { 
    final ResourceDatabasePopulator populator = new ResourceDatabasePopulator(); 
    populator.addScript(schemaScript); 
    populator.addScript(dataScript); 
    return populator; 
} 
+0

Sembra ragionevole, ma penso che sarebbe necessario essere all'interno di un bean per ottenere le annotazioni '@ Value' cablate? È molto diverso dall'usare l'attributo di configurazione che l'OP stava cercando di evitare? (Dalla sua risposta, OP stava provando a installare un test unitario che non sarebbe stato di aiuto con entrambi credo.) – Rup

+0

sì, questo non aiuta molto più della mia risposta, almeno per il mio caso d'uso –

+0

Nel mio caso questo inizializzatore lo script verrà eseguito ad ogni avvio ... come posso limitarlo al primo avvio? –

23

si deve creare il proprio schema.sql e metterlo nel vostro src/main/resources -cartella.

import javax.sql.DataSource; 

import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.core.io.ClassPathResource; 
import org.springframework.jdbc.datasource.SimpleDriverDataSource; 
import org.springframework.jdbc.datasource.init.DatabasePopulator; 
import org.springframework.jdbc.datasource.init.DatabasePopulatorUtils; 
import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator; 

@Configuration 
public class DataSourceInitializer { 

    @Bean(name = "dataSource") 
    public DataSource getDataSource(){ 
     DataSource dataSource = createDataSource(); 
     DatabasePopulatorUtils.execute(createDatabasePopulator(), dataSource); 
     return dataSource; 
    } 

    private DatabasePopulator createDatabasePopulator() { 
     ResourceDatabasePopulator databasePopulator = new ResourceDatabasePopulator(); 
     databasePopulator.setContinueOnError(true); 
     databasePopulator.addScript(new ClassPathResource("schema.sql")); 
     return databasePopulator; 
    } 

    private SimpleDriverDataSource createDataSource() { 
     SimpleDriverDataSource simpleDriverDataSource = new SimpleDriverDataSource(); 
     simpleDriverDataSource.setDriverClass(org.h2.Driver.class); 
     simpleDriverDataSource.setUrl("jdbc:h2:target/database/example;AUTO_RECONNECT=TRUE"); 
     simpleDriverDataSource.setUsername(""); 
     simpleDriverDataSource.setPassword(""); 
     return simpleDriverDataSource;  
    } 
} 
+1

grazie, ma non è sicuro che aggiunga nulla alle risposte esistenti? –

+1

@SebastienLorber Ho riscontrato alcuni problemi con l'annotazione Value, quindi ho dovuto riscriverlo. E sopra è il mio risultato e funziona :) –

+0

Grazie funziona. @ Arcone – Xelian

Problemi correlati