2011-10-19 60 views
14

我想使用HSQL內存數據庫對MyBatis持久層進行單元測試。真正的應用程序使用Oracle數據庫。這工作得很好,我們開始爲id列添加自動遞增的數字。 Oracle需要使用序列來獲取增加的數字,以便在Oracle數據庫中創建一個名爲basis_seq的序列。在我的MyBatis映射器XML文件,我有這樣的:使用HSQL代替Oracle的單元測試MyBatis

<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: 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

據我瞭解「雙反」是某種虛擬在Oracle中存儲序列的表,我沒有在我的測試數據庫中。如果我刪除<selectKey> -tag單元測試工作(因爲HSQL可以自動生成標記爲identity的列的ID),但不是真正的應用程序。一種解決方法是爲單元測試創​​建單獨的MyBatis映射XML文件,而不使用<selectKey>-tag,但這是不受歡迎的,因爲我想測試真實配置。

有沒有辦法在HSQL中創建和使用一個序列,或者也許有一些MyBatis的解決方法呢?或者我應該使用另一個數據庫來進行像H2這樣的單元測試?


我用:

  • 春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; 

(如果您在單元測試期間多次運行此腳本,請記住將drop sequence BASIS_SEQ if exists;添加到schema.sql的頂部)

+1

Luwil:你知道你可以給你自己的問題添加一個答案,如果你想分享你應用到你的問題的解決方案... –

回答

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

SQL語法兼容不斷擴大在HSQLDB的新版本,所以最好使用最新版本。

+0

謝謝@fredt,作品像一個魅力。對於其他使用Spring的人,我會將文本添加到我的問題中,詳細說明如何更改我的配置(很難在註釋中獲得格式化權限)。 – Luwil

2

您仍然可以使用原來的4行配置,使用<jdbc:embedded-database ...>。就在您的測試數據/ schema.sql文件文件的開頭添加以下行:

SET DATABASE SQL SYNTAX ORA TRUE; 

這是作爲附加sql.syntax_ora=true你的JDBC URL effectivelly相同。