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

标签 oracle hsqldb mybatis

我想使用 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: 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



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

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

我用:
  • Spring 3.0.5
  • HSQL 2.2.4
  • MyBatis 3.0.5


  • 更新:

    得到答复后弗雷特 ,这是我编辑 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;)

    最佳答案

    最新的 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 的新版本中不断扩展,因此最好使用最新的可用版本。

    关于oracle - 使用 HSQL 而不是 Oracle 对 MyBatis 进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7819808/

    相关文章:

    oracle - 允许 Oracle 用户仅从一个 IP 地址连接

    java - 使用 JDBC 运行 Drop Tablespace 命令时,操作系统中的数据文件未删除

    java - HSQLDB - 改变表模式

    java - 是否可以从 Spring Boot 应用程序压缩嵌入式 HSQL DB?

    java - Mybatis SQL session 提交看起来比以下代码慢

    java - MyBatis - 使用自定义对象调用存储过程

    java - 在 Debian Linux 上安装 Oracle SQL Developer 时出现问题

    java - 使用 HSQLDB JDBC 驱动程序在 CSV 上执行 SQL

    java - Mybatis 无法绑定(bind)数据

    oracle - 为什么我不能使用 SQLcl 通过 jdbc 连接