【问题标题】:Build up dynamic table joins in JOOQ在 JOOQ 中建立动态表连接
【发布时间】:2019-09-02 10:38:42
【问题描述】:

我使用 JOOQ 作为 SQL 构建器工具,然后在 jdbcTemplate 中执行。我需要动态地将表连接添加到 from 子句。目前我正在这样做..

SelectJoinStep<?> selectClause = select(field("ColumnA"), field("ColumnB"))
.from(table("TableA"));

if(condition) {
  selectClause.join(table("TableB), JoinType.JOIN).on(field("columnA").eq(field("columnB")));
}

然后我将 select 子句与 where 子句结合起来..

org.jooq.Query ps = selectClause.where(whereClause);

这工作正常,但现在我想引入分页,所以我需要将选定的字段换出一个简单的计数,如果我可以在这个计数查询中重用 from 子句会很好,但我不能因为选择和 from 子句在同一个变量中。

更新.. 为什么我不能像这样动态地构建 from 子句...

    List<Field<?>> fields = new ArrayList<Field<?>>();
    fields.add(...);
    Table<?> from = table("TableA");
    if(condition) {
      from.join(table("TableB), JoinType.JOIN).on(field("columnA").eq(field("columnB")));
    }
org.jooq.Query ps = select(fields).from(from);

如果条件为真,表连接不会出现在生成的 SQL 中?

【问题讨论】:

  • “我使用 JOOQ 作为 SQL 构建器工具,然后在 jdbcTemplate 中执行” - 为什么不直接使用 jOOQ 执行?

标签: java sql jooq


【解决方案1】:

将 jOOQ 用于动态 SQL 的最佳方法是 a more functional approach。不要考虑在某些条件下“交换”部分查询。想想你的查询的哪些部分是由谁通过函数提供的?例如:

ResultQuery<?> query(
    Supplier<Collection<SelectField<?>>> select,
    boolean condition,
    boolean paginate
) {
    Condition whereClause = ...;
    Table<?> from = table("TableA");
    if (condition)
        from = from.join(table("TableB")).on(field("ColumnA").eq(field("ColumnB")));

    return select(select.get())
          .from(from)
          .where(whereClause)
          .limit(paginate ? 10 : Integer.MAX_VALUE); // Could be done differently
}

现在调用上面的:

query(() -> Arrays.asList(field("ColumnA"), field("ColumnB")), true, true);
query(() -> Arrays.asList(count()), true, false);

当然,另一种选择是使用窗口函数来计算该计数值,而不是运行两个查询:

count().over()

【讨论】:

  • 感谢您的回答,我将探索这种方法,但您能看看我上面的更新。
  • @jonesy:请仔细看看我是怎么写的。 Table.join() 不是变异操作。您必须将结果表重新分配给本地变量。
猜你喜欢
  • 2018-04-09
  • 1970-01-01
  • 1970-01-01
  • 2018-03-29
  • 2023-03-22
  • 1970-01-01
  • 2016-02-21
  • 2012-12-12
  • 1970-01-01
相关资源
最近更新 更多