简体   繁体   中英

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

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?

I want to execute case expression and get data.. I am trying with JSQLParser. Above example should return "Test1" as output

but why are you trying to do that? Is your intention to unit test your query? or the code that calls the query?

If you're trying to unit test database objects, you might be better of putting it into a proc and utilizing a database unit testing framework. Some info on oracle unit testing . I'm assuming oracle based on dual.

If you're trying to test your java code, you need to think about pulling the query directly out of the method you're attempting to test, and programming to an interface to which you can provide "real" implementation, and a mock or fake implementation. This way you're testing independent of the db call itself.

An example of what I mean in code, and sorry this is going to be a little rough as I'm less familiar with java compared to c#

say you have:

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?
    }
}

So, as stated above if your intention is to test the SQL itself, you should probably pull the literal SQL out, put it in a stored procedure, and use a unit testing framework to test the outcome of the proc under multiple scenarios like param value = 1, 2, and 3.

But, if you want to test the surrounding // Do stuff and/or // potentially do some other stuff? without depending on database connectivity, you'll need to do some relatively simple refactoring.

The method myMethodThatNeedsTesting has a dependency on the database, which we need to abstract away through the use of an interface, as to be able to test the method myMethodThatNeedsTesting without relying on a real database connection.

That could look something like this:

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

I've defined the above to be a representation of what the query represents. The query requires a parameter (param1) and returns a scalar string (result from your query).

Given this interface, you can refactor your original class to look more like this:

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?
    }
}

In the above, you can see that the method myMethodThatNeedsTesting is now no longer directly dependent on a database connection, but rather an interface. With this, we can now provide for testing purposes, a mock, stub, or fake .

An example fake could be:

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";
    }

Now with the above fake, you pass in the fake implementation in your constructor, and you can test myMethodThatNeedsTesting without relying on a database connection.

The above refactor can be defined as dependency injection , and is quite useful for loose coupling, which leads to more easily tested code, among other things.

Sorry if i messed up any syntax in the above, again java is not my language of choice :)

As you mentioned JSqlParser: There is a very simplistic example of expression evaluation. ( https://github.com/JSQLParser/JSqlParser/wiki/Example-of-expression-evaluation )

You could extend this to build an interpreter that fit your needs. Since JSqlParser is only a parser, this would be quite a task.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM