2012-02-17 7 views
33

Próbuję wykonać test jednostkowy mojego DAO (używając Spring i Hibernate). Korzystam z samouczka HSQLDB na temat this. Samouczek stwierdza, że ​​bazę danych HSQLDB w pamięci można zainicjować za pomocą skryptu SQL, ale nie mogę znaleźć informacji o tym, jak to zrobić na wiosnę. Oto odpowiednia konfiguracja kontekstu sprężynowego:Jak zainicjować HSQLDB w pamięci za pomocą skryptu za pomocą sprężyny

<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> 

Każda pomoc zostanie doceniona. Dzięki.

+1

'Różnica między trybem in-memory i file jest taka, że ​​baza danych w pamięci jest pusta, ale tryb plików jest inicjowany danymi. Jedną z strategii, którą stosowałem w przeszłości, jest utworzenie autonomicznej bazy danych, zezwolenie Hibernate na tworzenie tabel i dodawanie danych dla mnie, zapisywanie danych w skrypcie, a następnie używanie adresu URL opartego na plikach do wskazywania skryptu. Dobrą stroną skryptu jest to, że jest to surowy SQL, więc możesz wstępnie wypełnić bazę danych dowolnymi danymi, które chcesz przetestować. To z postu, który łączyłeś, wyraźnie wspomina o tym procesie. –

+0

Przeczytałem powyższe, ale myślę, że nie wstawiłem 2 i 2 razem, że wtedy używałbyś "pliku" wersji HSQLDB i zrobiłaby to w pamięci ze skryptem jako startowym. –

Odpowiedz

72

Jeśli próbujesz do pracy z bazami danych w pamięci i wiosną, jest nowy jdbc namespace for Spring 3 sprawia, że ​​praca z wbudowanych baz danych bardzo łatwe.

Najlepsze jest to, że działa jako DataSource, więc można go łatwo wrzucić do wymiany istniejącej fasoli dataSource.

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

Jeśli jesteś bardziej zainteresowany w ten sposób z Java Config, spójrz na EmbeddedDatabaseBuilder (nowy wiosną 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

To wygląda jak odpowiedź. Grałem z HSQLDB i wbudowaną bazą danych, próbując działać. Jak dotąd EB wydaje się działać dobrze. –

+2

+1. Moja [odpowiedź] (http://stackoverflow.com/a/9329628/649852) działa dla Spring 2.X; teraz, gdy jesteśmy w Spring 3.X, myślę, że przejdziemy do tego podejścia. –

+0

Znalazłem to po prostu krążące w dokumentacji Spring 3 około 6 miesięcy temu. Jest niezwykle łatwy w użyciu (nie jest to metoda twojej odpowiedzi) i byłem w stanie przetestować go już kilka razy. –

3

W tutorialu masz łącze, jeden ze sposobów ustalania rzeczy jest to (po oczywista korekta):

  • w pamięci ze skryptu: jdbc:hsqldb:file:path-to-file

Myślę, że wydaje się to istotne. Proponuję zastąpienie path-to-file z czymś, co wygląda jak w pełni kwalifikowanej nazwy pliku ...

+0

Ale czy to utrzymuje DB w pliku zamiast w pamięci? Czy mogę założyć, że jest to bezpieczne, jeśli wycofam wszystkie transakcje? –

+0

@John: Zwykle utrzymuje go w pamięci domyślnie (konfigurowalny w oparciu o tabelę), chociaż spowoduje migrację na dysk, więc będzie się utrzymywał. Niestety, dokumentacja nie jest bardzo jasna co do szczegółów tego, co dokładnie tam musi być; Sądzę, że będziesz musiał trochę poeksperymentować i wszystko stanie się jasne. (To jest trochę ułomne z mojej strony ...) –

+1

Dla przyszłego odniesienia innych osób: kiedy to robisz, uruchamia się to głównie w pamięci, jest bardzo szybki, ale jeśli wprowadzisz zmiany, to ostatecznie je spłucze z powrotem na dysk, co prawdopodobnie nie jest tym, czego potrzebujesz. Aby to naprawić, musisz ustawić opcję hsqldb 'files_readonly'. Wykonanie tego w łańcuchu połączenia jest niepoprawne, ale możesz to zrobić w pliku właściwości DB: Po pierwszym uruchomieniu powyższego, utworzy on [ścieżka-do-pliku] .properties, jeśli jeszcze nie istnieje . Dodaj nową linię mówiącą "hsqldb.files_readonly = true" na końcu tego, i gotowe. –

2

Można obejść ten problem poprzez utworzenie podklasy BasicDataSource z pobierające/ustawiające dla dwóch nowych właściwości, initExecuteSqlFile i destroyExecuteSqlFile, które mogą mieć oddzielone przecinkami lista plików SQL do wykonania. Podklasa miałaby metody, które obsługują pliki SQL inicjujące/niszczące.

Następnie użyj następującą definicję Fasola:

<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

Nadal musimy implementować pewną logikę zapełniania wewnątrz init()? – udalmik

5

Nicholas odpowiedź jest idealnie czysty, ale można użyć jdbc nazw zainicjować zewnętrznej bazy danych, a także:

<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

Dzięki wbudowanej bazie danych chcemy być tylko w stanie połączyć się z bazą danych z tego samego JVM. Jeśli mamy dwa JVMs, dla wydajności lub innych ograniczeń, możemy:

  1. Zamiast osadzony-bazy danych, można użyć źródła danych sugeruje this answer.

  2. Następnie zainicjuj jak sugerowane Poitrek De (i zasugerowano również w previous answer). Możesz tworzyć tabele tylko wtedy, gdy nie istnieją (zgodnie z sugestią here).

Powiązane problemy