1

Can we execute SQL without having a real database connection in java? example:

 SELECT CASE
          WHEN :param = 1 THEN 'TEST1'
          WHEN :param = 2 THEN 'TEST2'
          WHEN :param = 3 THEN 'TEST3'
       END
          AS RESULT
FROM DUAL

I will replace :param in runtime in java code. Is there any way to do this?

I found this link: How do I extract selected columns given an Oracle SQL String?

but no quick solution is provided in this link

Currently thinking of: dummy hsqldb connection and execute SQL query. But it requires to span a new in memory db.

Is there any better & quick solution?

4

2 回答 2

0

正如您提到的 JSqlParser:有一个非常简单的表达式评估示例。(https://github.com/JSQLParser/JSqlParser/wiki/Example-of-expression-evaluation

您可以扩展它以构建适合您需求的解释器。由于 JSqlParser 只是一个解析器,这将是一项艰巨的任务。

于 2016-06-08T08:08:24.220 回答
0

我想执行 case 表达式并获取数据。我正在尝试使用 JSQLParser。上面的例子应该返回“Test1”作为输出

但你为什么要这么做?您是否打算对查询进行单元测试?或调用查询的代码?

如果您尝试对数据库对象进行单元测试,最好将其放入 proc 并利用数据库单元测试框架。 关于 oracle 单元测试的一些信息。我假设甲骨文基于双重。

如果您正在尝试测试您的 java 代码,您需要考虑将查询直接从您尝试测试的方法中提取出来,并编程到您可以提供“真实”实现的接口,以及一个模拟或假执行。这样,您就可以独立于 db 调用本身进行测试。

我在代码中的意思的一个例子,对不起,这会有点粗糙,因为与 c# 相比,我对 java 不太熟悉

说你有:

public class ClassINeedToTest {
    public void myMethodThatNeedsTesting(int param1) {
        // do some stuff

        // implementation of sql code ... not real since I don't know how to call SQL from java
        SELECT CASE
          WHEN :param = 1 THEN 'TEST1'
          WHEN :param = 2 THEN 'TEST2'
          WHEN :param = 3 THEN 'TEST3'
        END
          AS RESULT
        FROM DUAL

        // potentially do some other stuff?
    }
}

因此,如上所述,如果您的意图是测试 SQL 本身,您可能应该将文字 SQL 提取出来,将其放入存储过程中,并使用单元测试框架在参数值等多种场景下测试 proc 的结果= 1、2 和 3。

但是,如果您想测试环境// Do stuff和/或// potentially do some other stuff?不依赖于数据库连接,则需要进行一些相对简单的重构。

该方法myMethodThatNeedsTesting对数据库有依赖性,我们需要通过使用接口将其抽象出来,以便能够在myMethodThatNeedsTesting不依赖真实数据库连接的情况下测试该方法。

这可能看起来像这样:

public interface ISomeInterface {
    string getInfo(int param1);
}

我已将上述内容定义为查询所代表的内容。该查询需要一个参数 (param1) 并返回一个标量字符串(查询的结果)。

给定这个接口,你可以重构你的原始类看起来更像这样:

public interface ISomeInterface {
    string getInfo(int param1);
}

public class MySomeInterfaceImpl implements ISomeInterface {
    @override
    public string getInfo(int param1) {
        // implementation of sql code ... not real since I don't know how to call SQL from java
        SELECT CASE
          WHEN :param = 1 THEN 'TEST1'
          WHEN :param = 2 THEN 'TEST2'
          WHEN :param = 3 THEN 'TEST3'
        END
          AS RESULT
        FROM DUAL
    }
}

public class ClassINeedToTest {

    private ISomeInterface _myInterface;

    public ClassINeedToTest(ISomeInterface iSomeInterface) {
        _myInterface = iSomeInterface;
    }

    public void myMethodThatNeedsTesting(int param1) {
        // do some stuff

        _myInterface.getInfo(param1);

        // potentially do some other stuff?
    }
}

在上面,您可以看到该方法myMethodThatNeedsTesting现在不再直接依赖于数据库连接,而是一个接口。有了这个,我们现在可以提供用于测试目的的 mock、stub 或 fake

一个假的例子可能是:

public class MySomeInterfaceFake implements ISomeInterface {
    @override
    public string getInfo(int param1) {
        if (param1 == 1)
            return "TEST1";
        if (param1 == 2)
            return "TEST2";
        if (param1 == 3)
            return "TEST3";
    }

现在有了上面的假,你在你的构造函数中传入了假的实现,你可以myMethodThatNeedsTesting在不依赖数据库连接的情况下进行测试。

上面的重构可以定义为依赖注入,并且对于松散耦合非常有用,这会导致更容易测试的代码等等。

抱歉,如果我搞砸了上面的任何语法,java 又不是我选择的语言 :)

于 2016-06-03T08:23:02.643 回答