Модульное тестирование MyBatis с использованием HSQL вместо Oracle

#oracle #hsqldb #mybatis

#Oracle #hsqldb #mybatis

Вопрос:

Я хотел бы провести модульное тестирование моего уровня сохраняемости MyBatis, используя базу данных HSQL в памяти. Реальное приложение использует базу данных Oracle. Это отлично сработало, когда мы начали добавлять автоматически увеличиваемые числа для столбцов идентификаторов. Oracle требует использования последовательности для получения увеличенного числа, поэтому в базе данных Oracle была создана последовательность с именем basis_seq. В моем XML-файле MyBatis mapper у меня есть это:

 <insert id="insertBasis" parameterType="com.foo.Basis" useGeneratedKeys="true" keyProperty="id">
        <selectKey resultType="long" keyProperty="id" order="BEFORE">
            SELECT basis_seq.NEXTVAL FROM DUAL
        </selectKey>
        insert into basis
        (id, name)
        values
        (#{id}, #{name})
</insert>
  

Это работает, когда я запускаю приложение, но модульный тест выдает ошибку:

org.springframework.jdbc.BadSqlGrammarException: ошибка выбора ключа или установки результата в объект параметра. Причина: java.sql.SQLSyntaxErrorException: пользователю не хватает привилегий или объект не найден: DUAL ; неправильная грамматика SQL []; вложенным исключением является java.sql.SQLSyntaxErrorException: пользователю не хватает привилегий или объект не найден: DUAL

Насколько я понимаю, «DUAL» — это какая-то виртуальная таблица в Oracle, в которой хранятся последовательности, и у меня нет этого в моей тестовой базе данных. Если я удалю <selectKey> -tag, модульный тест сработает (поскольку HSQL может автоматически генерировать идентификаторы для отмеченных столбцов identity ), но не для реального приложения. Одним из обходных путей было бы создание отдельных XML-файлов MyBatis mapper для модульных тестов без <selectKey> тега -, но это нежелательно, поскольку я хочу протестировать реальную конфигурацию.

Есть ли способ создать и использовать последовательность в HSQL или, может быть, какой-нибудь обходной путь MyBatis для этого? Или я должен использовать другую базу данных для моего модульного теста, например, H2?


Я использую:

  • Весна 3.0.5
  • HSQL 2.2.4
  • MyBatis 3.0.5

Обновить:

После получения ответа от фредта, вот как я отредактировал свою конфигурацию Spring:

Прежде чем я определил свой источник данных с помощью:

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

Теперь я делаю это:

 <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
    destroy-method="close">
    <property name="driverClassName" value="org.hsqldb.jdbcDriver" />
    <property name="url" value="jdbc:hsqldb:mem:test;sql.syntax_ora=true" />
    <property name="username" value="sa" />
    <property name="password" value="" />
</bean>

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

Кроме того, в schema.sql мне нужно создать последовательности:

 CREATE SEQUENCE BASIS_SEQ START WITH 1000 INCREMENT BY 1;
CREATE SEQUENCE OTHER_SEQ START WITH 1000 INCREMENT BY 1;
  

(если вы запускаете этот скрипт много раз во время модульного тестирования, не забудьте добавить drop sequence BASIS_SEQ if exists; в начало schema.sql)

Комментарии:

1. Luwil: Вы знаете, что можете добавить ответ на свой собственный вопрос, если хотите поделиться решением, которое вы применили к своему вопросу…

Ответ №1:

Последняя версия HSQLDB обеспечивает полную совместимость с синтаксисом Oracle. Все, что вам нужно, это добавить sql.syntax_ora=true URL-адрес вашей базы данных. Например:

 jdbc:hsqldb:mem:test;sql.syntax_ora=true
  

Смотрите Руководство

http://hsqldb.org/doc/2.0/guide/deployment-chapt.html

http://hsqldb.org/doc/2.0/guide/dbproperties-chapt.html

Совместимость синтаксиса SQL постоянно расширяется в новых версиях HSQLDB, поэтому лучше всего использовать последнюю доступную версию.

Комментарии:

1. Спасибо @fredt, работает как шарм. Для других, использующих Spring, я добавлю текст к своему вопросу с подробным описанием того, как я изменил свою конфигурацию (трудно получить правильное форматирование в комментарии).

Ответ №2:

Вы все равно можете использовать свою исходную конфигурацию из 4 строк, используя <jdbc:embedded-database ...> . Просто добавьте следующую строку в начале вашего файла test-data / schema.sql:

 SET DATABASE SQL SYNTAX ORA TRUE;
  

Это фактически то же самое, что и добавление sql.syntax_ora=true к вашему URL-адресу JDBC.