Unit test MyBatis с HSQL вместо Oracle
Я хотел бы unit test мой уровень сохранения MyBatis с использованием базы данных в базе данных HSQL. Реальное приложение использует базу данных Oracle. Это сработало отлично, мы начали добавлять автоматически увеличивающиеся числа для столбцов id. Oracle требует использования последовательности для получения добавочного номера, поэтому в базе данных Oracle была создана последовательность, называемая base_seq. В моем XML файле MapBashis 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>
Это работает, когда я запускаю приложение, но unit test получает сообщение об ошибке:
org.springframework.jdbc.BadSqlGrammarException: ошибка при выборе ключа или задание результата для объекта параметра. Причина: java.sql.SQLSyntaxErrorException: пользователю не хватает привилегии или объекта, а не найдено: DUAL; плохая грамматика SQL []; вложенное исключение java.sql.SQLSyntaxErrorException: пользователю не хватает привилегии или объекта, а не найдено: DUAL
Как я понимаю, "DUAL" - это какая-то виртуальная таблица в Oracle, которая хранит последовательности, и у меня ее нет в моей тестовой базе данных. Если я удалю <selectKey>
-tag работу unit test (поскольку HSQL может автогенерировать идентификаторы для столбцов с пометкой identity
), но не для реального приложения. Одним из способов было бы создать отдельные XML файлы MyBatis mapper для модульных тестов без <selectKey>
-tag, но это нежелательно, так как я хочу проверить реальную конфигурацию.
Есть ли способ создать и использовать последовательность в HSQL или, может быть, обходной путь MyBatis для этого? Или я должен использовать другую базу данных для моего unit test как H2?
Я использую:
- Spring 3.0.5
- HSQL 2.2.4
- MyBatis 3.0.5
UPDATE:
После получения ответа от fredt, вот как я отредактировал конфигурацию 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;
(если вы запускаете этот script много раз во время модульного тестирования, не забудьте добавить drop sequence BASIS_SEQ if exists;
в начало schema.sql)
Ответы
Ответ 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, поэтому лучше использовать последнюю доступную версию.
Ответ 2
Вы можете использовать исходную 4-строчную конфигурацию, используя <jdbc:embedded-database ...>
. Просто добавьте следующую строку в начале файла test-data/schema.sql:
SET DATABASE SQL SYNTAX ORA TRUE;
Это так же, как добавление sql.syntax_ora=true
к вашему URL JDBC.