【问题标题】:How do I create a Dynamic Sql Query at runtime using JDBI's Sql Object API?如何使用 JDBI 的 Sql 对象 API 在运行时创建动态 Sql 查询?
【发布时间】:2013-09-09 16:10:04
【问题描述】:

我一直在将现有项目从 jdbc 迁移到 jdbi,并且我一直在充分利用 jdbi 漂亮的 SQL 对象 API。我们正在使用 mysql。

虽然 SQL 对象 API 可以构造在编译时已知的已处理查询,但我找不到在运行时生成查询的方法。

具体来说,我希望能够做这样的事情:

@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
);

【问题讨论】:

    标签: java mysql sql jdbi


    【解决方案1】:

    请参阅@Define 注释和 UseStringTemplate3StatementLocator 用法。

    【讨论】:

    • 完美!这只是给了我一个继续使用 JDBI 的理由
    • 我已经查看了 @Define@UseStringTemplate3StatementLocator 注释,但我看不出它们中的一个或两个如何结合起来解决 OP 的问题。能否请您解释的更详细一点,或者提供一个例子?
    【解决方案2】:

    JDBI 不太适合构建动态查询。 IMO 这个库的重点是尽可能地分离代码和 SQL 查询。

    但是,您的特殊情况可能会通过 SQL 解决:

    COALESCE(:foo, foo) 
    

    如果 'foo' 是表中列的名称,并且 :foo 将解析为 NULL,则 mysql SET 将有效

    SET foo=foo
    

    即它不会做任何事情(在您的情况下这是理想的行为)。如果 :foo 不为空,则相当于

    SET foo=:foo
    

    【讨论】:

    • 这就是我最终所做的。我应该补充一点,您应该创建一个自定义 @Binder 对象来处理其他条件,即如果不为零则更新。
    【解决方案3】:

    您可以编写如下查询:

    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
    

    换句话说,如果它匹配条件,则将列设置为变量,否则将其设置为自身(即不设置它)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-08-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-30
      • 1970-01-01
      相关资源
      最近更新 更多