2012-02-17 3 views
33

Я пытаюсь выполнить модульное тестирование моего DAO (используя Spring и Hibernate). Я использую HSQLDB за this. В учебнике указано, что база данных HSQLDB в памяти может быть инициализирована с использованием сценария SQL, но я не могу найти информацию о том, как это сделать весной. Вот соответствующая конфигурация контекста весны:Как инициализировать HSQLDB в памяти с использованием скрипта через 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> 

Любая помощь будет оценена по достоинству. Благодарю.

+1

'Разница между режимом работы в памяти и файлом заключается в том, что база данных в памяти пуста, но режим файла инициализируется данными. Одна из стратегий, которую я использовал в прошлом, - создать автономную базу данных, позволить Hibernate создавать таблицы и добавлять данные для меня, сохранять данные в сценарий и затем использовать URL-адрес на основе файлов, чтобы указать на скрипт. Хорошая вещь о скрипте заключается в том, что он является сырым SQL, поэтому вы можете предварительно заполнить базу данных любыми данными, которые хотите протестировать. «Это из поста, который вы связали, он четко упоминает процесс. –

+0

Я прочитал выше, но я думаю, что я не поставил 2 & 2 вместе, чтобы тогда вы использовали «файловую» версию HSQLDB, и это сделало бы в памяти со сценарием в качестве запуска. –

ответ

72

Если вы пытаетесь работать с в памяти баз данных и весне, есть новый jdbc namespace for Spring 3, что делает работу с встроенными базами данных очень легко.

Лучшая часть состоит в том, что она действует как DataSource, поэтому ее можно легко отбросить, чтобы заменить существующий фасоль dataSource.

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

Если вы больше заинтересованы в этом с Java Config, посмотрите на EmbeddedDatabaseBuilder (новый весной 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

Это похоже на ответ. Я играл с HSQLDB и встроенной базой данных, пытаясь либо работать. Пока что ЭБ работает хорошо. –

+2

+1. Мой [ответ] (http://stackoverflow.com/a/9329628/649852) работает для Spring 2.X; теперь, когда мы находимся в Spring 3.X, я думаю, мы перейдем к этому подходу. –

+0

Я нашел, что это всего лишь крейсерская документация весны 3 около 6 месяцев назад. Он невероятно прост в использовании (не то, что у вашего метода ответа нет), и я уже мог опробовать его несколько раз. –

3

В учебнике вы ссылка, один из способов настройки вещи это (после того, как очевидно, коррекция):

  • В памяти из сценария: jdbc:hsqldb:file:path-to-file

Я думаю, что это будет иметь значение. Я предлагаю заменить path-to-file с чем-то, что выглядит как полное имя файла ...

+0

Но поддерживает ли это БД в файле, а не в памяти? Могу ли я предположить, что это безопасно, если я откажусь от всех операций? –

+0

@John: Обычно он сохраняет его в памяти по умолчанию (настраивается на основе таблицы), хотя он перенесет его на диск, чтобы он сохранялся. Увы, документация не очень четко описывает мелкие детали того, что именно должно быть там; Думаю, вам придется немного поэкспериментировать, и все станет ясно. (Это немного хромота, чтобы сказать с моей стороны ...) –

+1

Для будущих людей других людей: когда вы это делаете, он запускает ее главным образом в памяти, она очень быстрая, но если вы вносите изменения, она в конечном итоге очистит их назад к диску, который, вероятно, не тот, который вы хотите. Чтобы исправить это, вам необходимо установить параметр hsqldb 'files_readonly'. Выполнение этого в строке соединения недопустимо, но вы можете сделать это в файле свойств DB: в первый раз, когда вы запустите вышеуказанное, оно создаст свойства [путь к файлу], если он еще не существует , Добавьте новую строку с надписью «hsqldb.files_readonly = true» до конца, и все готово. –

2

Вы можете обойти эту проблему, создав подкласс BasicDataSource с геттеры/сеттеры для двух новых свойств, initExecuteSqlFile и destroyExecuteSqlFile, которые могут иметь запятыми в качестве разделителей список исполняемых файлов SQL. В подклассе были бы init() и destroy() методы, которые обрабатывают файлы init/destroy SQL.

Затем используйте следующее определение бин:

<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

Итак, нам еще нужно реализовать некоторую заселяющую логику внутри init()? – udalmik

5

Николас Ответ прекрасно, но вы можете использовать jdbc пространство имен для инициализации внешней базы данных, а также:

<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

Благодаря встроенной БД-мы бы только возможность подключения к базе данных из того же JVM. Если у нас есть два JVMs, для исполнения или других ограничений, мы можем:

  1. Вместо того, чтобы использовать встроенную базу данных-, вы можете использовать источник данных предложен в this answer.

  2. Затем инициализируйте, например, Poitrek De (и предлагается в previous answer). Вы можете создавать таблицы только в том случае, если они не существуют (как предложено here).