如何跳过测试代码或将 oracle 语法转换为 h2

Posted

技术标签:

【中文标题】如何跳过测试代码或将 oracle 语法转换为 h2【英文标题】:How to skip code for testing or convert oracle syntax to h2 【发布时间】:2015-10-29 15:36:14 【问题描述】:

我和我的团队正在使用 oracle 数据库进行开发和生产。但为了节省时间,我们决定使用 H2 数据库进行测试,因为它速度快。

现在我们遇到了一个与 SQL 语法有关的问题。

public void lock(Collection<String> locks) 
    if (locks== null || locks.size() == 0)
        return;

    Connection dbc = null;
    Statement st = null;
    String q = null;
    try 
        dbc = db.getConnection();
        dbc.setAutoCommit(false);
        st = dbc.createStatement();
        st.setFetchSize(fetchSize);
        q = "LOCK TABLE resource_lock IN EXCLUSIVE MODE";
        st.executeUpdate(q);

        // Update the lock info in DB
        List idLists = DbUtil.splitIdList(locks);
        Iterator i = idLists.iterator();
        while (i.hasNext()) 
            List idList = (List) i.next();
            q =
                "DELETE FROM resource_lock\n" +
                "WHERE " + DbUtil.generateStrIn("lock", idList);
            st.executeUpdate(q);
        

        st.close();
        st = null;
        dbc.commit();
        dbc.close();
        dbc = null;
     catch (SQLException e) 
        throw new DbException(e, q);
     finally 
        DbUtil.cleanup(log, null, st, dbc);
    

问题发生在 “在独占模式下锁定表资源锁定” 这是 oracle 唯一的语法。在我写的测试中,它总是抛出语法错误,指出

Caused by: com.resource.db.DbException: Database Error: Syntax error in SQL statement "LOCK[*] TABLE RESOURCE_LOCK IN EXCLUSIVE MODE "; SQL statement:
LOCK TABLE resource_lock IN EXCLUSIVE MODE [42000-160]
Last SQL was:
LOCK TABLE resource_lock IN EXCLUSIVE MODE

我想知道 H2 是否有具有等效操作的语法。 如果没有,那么我想知道如何跳过这一部分进行测试,因为许多其他类方法都使用它来更新数据库。 我不希望其他测试因此而失败。

【问题讨论】:

无意冒犯,但你到底是如何在与开发和生产完全不同的平台上进行测试并假设你的测试以任何方式有效的呢?这就像在人行道上开发和比赛您的汽车,但在海洋中进行测试...... @user3659052 不是不同的平台。你错了。 还有另一个例子,为什么在与生产环境不同的 DBMS 上进行测试是个坏主意。 horse 我们在 H2 中测试的原因是因为它很快,而且我们不希望在生产数据库中测试数据。 是的,但是您已将所有 SQL 嵌入到数据访问层中,除非它为各种底层数据库提供接口,否则该层包括特定于 DBMS 的语法。如果您想支持多个底层平台,则需要公开隐藏底层操作的应用程序代码使用的通用接口。而且我什至不会问您为什么理所当然地锁定满桌。如果您有任何重要的用户群在进行并发事务,那么这会咬到您 - 很难! 【参考方案1】:

要对不同的数据库使用不同的 SQL 命令,您可以为您的应用程序创建一个 DAO 层:

使用deleteLock()等方法创建接口, 在您的应用程序逻辑中,使用此方法而不是直接 SQL 查询 为不同的数据库创建 DAO 接口的多个实现 对 Oracle DB 使用“Oracle”实现,对 H2 使用“H2”实现

当然,测试与将在生产中运行的实现不同的实现会带来风险,但这就是您已经在做的事情。


示例:

我的服务:

private LockDao lockDao;
...
public void lock(Collection<String> locks) 
    ...
    lockDao.deleteLocks(locks);
    ...

锁道:

public void deleteLocks(Collection<String> locks);

OracleLockDao:

@Override
public void deleteLocks(Collection<String> locks) 
    ...
    q = "LOCK TABLE resource_lock IN EXCLUSIVE MODE";
    st.executeUpdate(q);
    ...
        q =
            "DELETE FROM resource_lock\n" +
            "WHERE " + DbUtil.generateStrIn("lock", idList);
        st.executeUpdate(q);
    ...

H2LockDao:

@Override
public void deleteLocks(Collection<String> locks) 
    // H2 implementation of lock deletion

【讨论】:

你到底是什么意思,能举个例子吗?

以上是关于如何跳过测试代码或将 oracle 语法转换为 h2的主要内容,如果未能解决你的问题,请参考以下文章

在 Java 中,如何将 String 转换为 char 或将 char 转换为 String?

如何迭代对象数组或将对象列表转换为数组?

如何将oracle中的解码功能转换为标准大查询

如何对 Javascript 对象进行排序,或将其转换为数组?

将 DB2 日期计算转换为 Oracle 语法

如何在 chromium 浏览器上创建文本或将文本转换为音频?