使用HSQL而不是Oracle对MyBatis进行单元测试

时间:2011-10-19 10:22:01

标签: oracle hsqldb mybatis

我想使用HSQL内存数据库对MyBatis持久层进行单元测试。真正的应用程序使用Oracle数据库。这工作得很好,我们开始为id列添加自动递增的数字。 Oracle需要使用序列来获取递增的数字,因此在Oracle数据库中创建了一个名为basis_seq的序列。在我的MyBatis映射器XML文件中,我有:

<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:user缺少权限或对象   发现:DUAL;糟糕的SQL语法[];嵌套异常是   java.sql.SQLSyntaxErrorException:user缺少权限或对象   发现:DUAL

据我所知,'DUAL'是Oracle中存储序列的某种虚拟表,我的测试数据库中没有这个。如果我删除<selectKey> - 标记单元测试工作(因为HSQL可以为标记为identity的列自动生成ID),但不是真实应用程序。一种解决方法是为单元测试创​​建单独的MyBatis映射器XML文件而不使用<selectKey> - 标签,但这是不希望的,因为我想测试真实的配置。

有没有办法在HSQL中创建和使用序列,或者为此可能有一些MyBatis解决方法?或者我应该使用另一个数据库进行我的单元测试,如H2?


我用:

  • Spring 3.0.5
  • HSQL 2.2.4
  • MyBatis 3.0.5

更新:

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;

(如果您在单元测试期间多次运行此脚本,请记住将drop sequence BASIS_SEQ if exists;添加到schema.sql的顶部)

2 个答案:

答案 0 :(得分:12)

最新的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

在新版HSQLDB中不断扩展SQL语法兼容性,因此最好使用最新版本。

答案 1 :(得分:2)

您仍然可以使用<jdbc:embedded-database ...>使用原始的4行配置。只需在test-data / schema.sql文件的开头添加以下行:

SET DATABASE SQL SYNTAX ORA TRUE;

这与将sql.syntax_ora=true附加到JDBC URL有效。