【发布时间】:2011-12-10 19:30:29
【问题描述】:
我想使用 HSQL 内存数据库对我的 MyBatis 持久层进行单元测试。实际应用程序使用 Oracle 数据库。这很好,因为我们开始为 id 列添加自动递增的数字。 Oracle 需要使用序列来获取递增的数字,因此在 Oracle 数据库中创建了一个名为 base_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:用户缺少权限或对象没有 发现:双;糟糕的 SQL 语法 [];嵌套异常是 java.sql.SQLSyntaxErrorException:用户缺少权限或对象没有 发现:双
据我了解,“DUAL”是 Oracle 中存储序列的某种虚拟表,而我的测试数据库中没有此表。如果我删除<selectKey>-tag 单元测试工作(因为HSQL 可以为标记为identity 的列自动生成ID)但不是真正的应用程序。一种解决方法是为没有<selectKey>-tag 的单元测试创建单独的 MyBatis 映射器 XML 文件,但这是不希望的,因为我想测试真实配置。
有没有办法在 HSQL 中创建和使用序列,或者可能有一些 MyBatis 解决方法?还是应该使用其他数据库进行单元测试,例如 H2?
我用:
- 春季 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;
(如果您在单元测试期间多次运行此脚本,请记住在 schema.sql 顶部添加 drop sequence BASIS_SEQ if exists;)
【问题讨论】:
-
Luwil:你知道你可以为自己的问题添加答案,如果你想分享你应用于你的问题的解决方案......