使用 HSQL 而不是 Oracle 对 MyBatis 进行单元测试
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7819808/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Unit test MyBatis with HSQL instead of Oracle
提问by Luwil
I would like to unit test my MyBatis persistence layer using an HSQL in-memory database. The real application uses an Oracle database. This worked fine unitl we started adding auto incremented numbers for the id columns. Oracle requires the use of a sequence to get the incremented number so a sequence called basis_seq was created in the Oracle database. In my MyBatis mapper XML file I have this:
我想使用 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>
This works when I run the application but the unit test gets an error:
这在我运行应用程序时有效,但单元测试出错:
org.springframework.jdbc.BadSqlGrammarException: Error selecting key or setting result to parameter object. Cause: java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: DUAL ; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: user lacks privilege or object not found: DUAL
org.springframework.jdbc.BadSqlGrammarException:选择键或将结果设置为参数对象时出错。原因:java.sql.SQLSyntaxErrorException:用户缺少权限或找不到对象:DUAL;错误的 SQL 语法 []; 嵌套异常是 java.sql.SQLSyntaxErrorException:用户缺少权限或找不到对象:DUAL
As I understand 'DUAL' is some kind of virtual table in Oracle that stores the sequences and I don't have this in my test database. If I remove the <selectKey>
-tag the unit test work (since HSQL can autogenerate ids for columns marked identity
) but not the real application. One workaround would be to create separate MyBatis mapper XML files for the unit tests without the <selectKey>
-tag but this is undesired since I want to test the real configuration.
据我了解,“DUAL”是 Oracle 中的某种虚拟表,用于存储序列,而我的测试数据库中没有它。如果我删除<selectKey>
-tag 单元测试工作(因为 HSQL 可以为标记的列自动生成 ID identity
)但不是真正的应用程序。一种解决方法是为不带<selectKey>
-tag的单元测试创建单独的 MyBatis 映射器 XML 文件,但这是不受欢迎的,因为我想测试实际配置。
Is there a way to create and use a sequence in HSQL as well or maybe some MyBatis workaround for this? Or should I use another database for my unit test like H2?
有没有办法在 HSQL 中创建和使用序列,或者可能有一些 MyBatis 解决方法?或者我应该使用另一个数据库来进行单元测试,比如 H2?
I use:
我用:
- Spring 3.0.5
- HSQL 2.2.4
- MyBatis 3.0.5
- 春天 3.0.5
- HSQL 2.2.4
- MyBatis 3.0.5
UPDATE:
更新:
After getting the answer from fredt, here is how I edited my Spring configuration:
从fredt得到答案后,以下是我编辑 Spring 配置的方式:
Before I defined my data source with:
在我定义我的数据源之前:
<jdbc:embedded-database id="dataSource">
<jdbc:script location="classpath:test-data/schema.sql" />
<jdbc:script location="classpath:test-data/data.sql" />
</jdbc:embedded-database>
Now I do this:
现在我这样做:
<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>
Also, in schema.sql I need to create the sequences:
此外,在 schema.sql 我需要创建序列:
CREATE SEQUENCE BASIS_SEQ START WITH 1000 INCREMENT BY 1;
CREATE SEQUENCE OTHER_SEQ START WITH 1000 INCREMENT BY 1;
(if you run this script many times during unit testing, remember to add drop sequence BASIS_SEQ if exists;
to top of schema.sql)
(如果你在单元测试期间多次运行这个脚本,记得添加drop sequence BASIS_SEQ if exists;
到 schema.sql 的顶部)
采纳答案by fredt
Latest HSQLDB provides extensive Oracle syntax compatibility. All you need is add sql.syntax_ora=true
to your database URL. For example:
最新的 HSQLDB 提供了广泛的 Oracle 语法兼容性。您所需要的只是添加sql.syntax_ora=true
到您的数据库 URL。例如:
jdbc:hsqldb:mem:test;sql.syntax_ora=true
See the Guide
请参阅指南
http://hsqldb.org/doc/2.0/guide/deployment-chapt.html
http://hsqldb.org/doc/2.0/guide/deployment-chapt.html
http://hsqldb.org/doc/2.0/guide/dbproperties-chapt.html
http://hsqldb.org/doc/2.0/guide/dbproperties-chapt.html
SQL syntax compatibility is constantly extended in new versions of HSQLDB, so it's best to use the latest available version.
SQL 语法兼容性在 HSQLDB 的新版本中不断扩展,因此最好使用最新的可用版本。
回答by Ales Dolecek
You can still use your original 4 line configuration using <jdbc:embedded-database ...>
. Just add following line at the beginning of your test-data/schema.sql file:
您仍然可以使用<jdbc:embedded-database ...>
. 只需在 test-data/schema.sql 文件的开头添加以下行:
SET DATABASE SQL SYNTAX ORA TRUE;
This is effectivelly same as appending sql.syntax_ora=true
to your JDBC URL.
这与附加sql.syntax_ora=true
到您的 JDBC URL有效相同。