2012-02-17 7 views
33

Sto tentando di eseguire il test dell'unità del mio DAO (utilizzando Spring e Hibernate). Sto usando HSQLDB per il tutorial this. Il tutorial afferma che il database HSQLDB in memoria può essere inizializzato usando uno script SQL ma non riesco a trovare informazioni su come farlo in primavera. Ecco la configurazione del contesto Spring pertinente:Come inizializzare HSQLDB in memoria utilizzando lo script tramite Spring

<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> 
    <property name="driverClassName" value="org.hsqldb.jdbcDriver" /> 
    <property name="url" value="jdbc:hsqldb:mem:mydb" /> 
    <property name="username" value="sa" /> 
    <property name="password" value="" /> 
    <property name="initialSize" value="5" /> 
    <property name="maxActive" value="10" /> 
    <property name="poolPreparedStatements" value="true" /> 
    <property name="maxOpenPreparedStatements" value="10" /> 
</bean> 

Qualsiasi aiuto sarebbe apprezzato. Grazie.

+1

'La differenza tra la modalità in-memory e file è che il database in memoria è vuoto, ma la modalità file è inizializzata con i dati. Una strategia che ho utilizzato in passato è quella di creare un database standalone, consentire a Hibernate di creare le tabelle e aggiungere dati per me, salvare i dati in uno script e quindi utilizzare l'URL basato su file per puntare allo script. La cosa buona dello script è che si tratta di SQL raw, quindi sei libero di precompilare il database con qualsiasi dato tu voglia testare. Questo dal post che hai collegato, menziona chiaramente il processo. –

+0

Ho letto quanto sopra, ma suppongo di non aver messo insieme 2 e 2 per utilizzare la versione "file" di HSQLDB e farebbe in-memory con lo script come avvio. –

risposta

72

Se si sta tentando di lavorare con i database in memoria e la primavera, c'è un nuovo jdbc namespace for Spring 3 che rende il lavoro con i database incorporati molto facile.

La parte migliore è che funge da DataSource, quindi può essere facilmente inserito per sostituire il bean esistente dataSource.

<jdbc:embedded-database id="dataSource" type="HSQL"> 
    <jdbc:script location="classpath:schema.sql"/> 
    <jdbc:script location="classpath:test-data.sql"/> 
</jdbc:embedded-database> 

Se siete più interessati a fare questo con Java Config, date un'occhiata alla EmbeddedDatabaseBuilder (nuova in primavera 3.0).

@Configuration 
public class DatabaseTestConfig { 
    @Bean 
    public DataSource dataSource() { 
     return new EmbeddedDatabaseBuilder() 
      .setType(EmbeddedDatabaseType.HSQL) 
      .addScript("classpath:schema.sql") 
      .addScript("classpath:test-data.sql") 
      .build(); 
    } 
} 
+0

Sembra la risposta. Stavo giocando con HSQLDB e database embedded cercando di funzionare. Finora l'EB sembra funzionare bene. –

+2

+1. La mia [risposta] (http://stackoverflow.com/a/9329628/649852) funziona per Spring 2.X; ora che siamo su Spring 3.X, penso che passeremo a questo approccio. –

+0

Ho trovato questo solo girando la documentazione Spring 3 circa 6 mesi fa. È incredibilmente facile da usare (non che il metodo della tua risposta non lo sia) e sono stato in grado di metterlo alla prova già una manciata di volte. –

3

Nel tutorial si collega a, uno dei modi per configurare le cose è questo (dopo ovvia correzione):

  • In-memory da uno script: jdbc:hsqldb:file:path-to-file

Penso che ciò sembrerebbe pertinente. Suggerisco di sostituire path-to-file con qualcosa che assomiglia a un nome di file pienamente qualificato ...

+0

Ma mantiene il DB nel file invece che nella memoria? Posso presumere che questo è sicuro se cancello tutte le transizioni? –

+0

@John: Generalmente lo mantiene in memoria per impostazione predefinita (configurabile su base tabella) anche se verrà migrato su disco in modo che possa persistere. Purtroppo, la documentazione non è molto chiara sui dettagli di ciò che deve essere esattamente lì; Immagino che dovrai sperimentare un po 'e tutto diventerà chiaro. (Questa è una cosa un po 'noiosa da parte mia ...) –

+1

Per riferimento futuro di altre persone: quando lo fai, lo esegue principalmente in memoria, è estremamente veloce, ma se apporti modifiche alla fine li svuoterà di nuovo sul disco, che probabilmente non è quello che vuoi. Per risolvere questo problema, è necessario impostare l'opzione hsqldb 'files_readonly'. L'operazione nella stringa di connessione non è valida, ma è possibile farlo nel file delle proprietà del database: questa prima volta che si esegue quanto sopra, verrà creato [path-to-file] .properties se non esiste già . Aggiungi una nuova riga alla fine di "hsqldb.files_readonly = true" e hai finito. –

2

Si potrebbe ovviare a questo con la creazione di una sottoclasse di BasicDataSource con getter/setter per due nuove proprietà, initExecuteSqlFile e destroyExecuteSqlFile, che può avere un separati da virgole elenco di file SQL da eseguire. La sottoclasse avrebbe i metodi init() e destroy() che gestiscono i file SQL di init/destroy.

quindi utilizzare la seguente definizione di fagioli:

<bean 
    id="datasource" 
    class="com.example.MyBasicDataSource" 
    destroy-method="destroy" 
    init-method="init" 
> 
    <property name="destroyExecuteSqlFile"> 
     <value>h2-destroy-01.sql</value> 
    </property> 
    <property name="initExecuteSqlFile"> 
     <value>h2-init-01.sql,h2-init-02.sql,h2-init-03.sql</value> 
    </property> 
    <!-- Other properties --> 
</bean> 
+0

Quindi dobbiamo ancora implementare alcune logiche di popolamento all'interno di init()? – udalmik

5

Nicholas risposta è perfettamente bene, ma è possibile utilizzare jdbc namespace per inizializzare database esterno così:

<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/DS"/> 

<jdbc:initialize-database data-source="dataSource"> 
    <jdbc:script location="classpath:/META-INF/database/init.sql"/> 
</jdbc:initialize-database> 
0

Con-database incorporato ci sarebbe solo essere in grado di connettersi al database dallo stesso JVM. Se abbiamo due JVM, per le prestazioni o altri vincoli, siamo in grado di:

  1. Invece di utilizzare un database incorporato, è possibile utilizzare l'origine dati ha suggerito in this answer.

  2. Quindi inizializzare come Poitrek De suggerito (e suggerito anche in previous answer). Si consiglia di creare tabelle solo se non esistono (come suggerito here).

Problemi correlati