4

I've been moving an existing project from jdbc to jdbi, and I've been making much use out of jdbi's beautiful SQL Object API. We're using mysql.

While the SQL Object API can construct handled queries that are known at compile time, I couldn't find a way of generating queries at run time.

Specifically, I want to be able to do something like this:

@SqlUpdate(
  "UPDATE record SET "+
    @IfNotZero("foo") "foo=:foo" +
    @IfNotNull("bar") "bar=:bar" +
    @IfNotNull("baz") "baz=:baz" +
  "WHERE id=:id"
)
public abstract int updateRecord(
  @Bind("id") int id,
  @Bind("foo") int foo,
  @Bind("bar") String bar,
  @Bind("baz") String baz
);

3 Answers 3

5

JDBI is not very well suited for constructing dynamic queries. IMO the whole point of this library is to separate code and SQL queries as much as possible.

However, your particular case might be solved by means of SQL:

COALESCE(:foo, foo) 

if 'foo' is the name of the column in the table, and :foo will resolve to NULL, then mysql SET will be effectively

SET foo=foo

i.e. it will do nothing (which is desired beaviour in your case). If :foo is not null, it will be equivalent to

SET foo=:foo
Sign up to request clarification or add additional context in comments.

1 Comment

That's what I ended up doing. I should add that you you should create a custom @Binder object to handle other conditions, i.e. Update if not zero.
4

See @Define annotation and UseStringTemplate3StatementLocator usage.

2 Comments

Perfect! This just gave me a reason to continue to use JDBI
I've looked at both the @Define and @UseStringTemplate3StatementLocator annotations, and I don't see how either or both of them could combine to solve the OP's problem. Could you please explain in a little more detail, or provide an example?
0

You can write a query like this:

UPDATE record SET
  foo = CASE WHEN :foo > 0 THEN :foo ELSE foo END
, bar = CASE WHEN :bar > 0 THEN :bar ELSE bar END
, baz = CASE WHEN :baz > 0 THEN :baz ELSE bar END
WHERE id = :id

In other words, you set the column to the variable if it matches condition, otherwise set it to itself (i.e. don't set it).

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.