1

Javaで実際のデータベース接続なしでSQLを実行できますか? 例:

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

Java コードの実行時に :param を置き換えます。これを行う方法はありますか?

このリンクを見つけました: Oracle SQL文字列を指定して選択した列を抽出するにはどうすればよいですか?

しかし、このリンクには簡単な解決策はありません

現在考えている: ダミーの hsqldb 接続と SQL クエリの実行。ただし、メモリ内の新しいデータベースにまたがる必要があります。

より良い&迅速な解決策はありますか?

4

2 に答える 2

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 を取り出してストアド プロシージャに入れ、ユニット テスト フレームワークを使用して、param 値などの複数のシナリオで 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がデータベース接続に直接依存するのではなく、インターフェイスに依存するようになっていることがわかります。これにより、テスト目的でモック、スタブ、またはフェイクを提供できるようになりました。

偽物の例は次のとおりです。

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 に答える
0

あなたが言及したように JSqlParser: 式評価の非常に単純な例があります。( https://github.com/JSQLParser/JSqlParser/wiki/式の評価例)

これを拡張して、ニーズに合ったインタープリターを構築できます。JSqlParser は単なるパーサーであるため、これはかなりの作業になります。

于 2016-06-08T08:08:24.220 に答える