JOOQ:动态连接条件

4
我希望能够在JOOQ中从这个

1
很抱歉,我不确定这里的动态部分应该是什么。建议编辑问题并提供一些细节。当mychecktrue/false时,所需的SQL查询是什么?问题描述得越完整,答案就会越好... - Lukas Eder
你不能在 if 语句中使用 select.whereselect.join 吗? - Antoniossss
1个回答

6

有几种解决方法:

使用隐式连接

在相对简单的情况下,当可选连接跟随一个对一关系时,您可以使用隐式连接(如果您正在使用代码生成器):

create.select()
      .from(TABLE_A)
      .join(TABLE_B).onKey(Keys.FK_TABLEA_TABLEB)
      .where(isFooSearched
        ? TABLE_B.tableC().FIELDC.containsIgnoreCase("foo")
        : noCondition())
      .fetch();

使用SEMI JOIN代替INNER JOIN,使动态SQL更加容易

create.select()
      .from(TABLE_A)
      .where(
          isFooSearched
        ? TABLE_A.TABLE_B_ID.in(
              select(TABLE_B.ID)
             .from(TABLE_B)
             .join(TABLE_C).onKey(FK_TABLEB_TABLEC)
             .where(TABLE_C.FIELDC.containsIgnoreCase("foo"))
          )
        : trueCondition())
      .fetch();

请注意,在这种情况下,半连接(semi join)比内连接更正式正确,因为在一对多关系中,您不会得到任何重复行 TABLE_A(使用DISTINCT删除它们可能是错误的,并且肯定效率低下)。
副笔:并非所有数据库都识别EXISTSIN语法中的半连接,因此与基于JOIN的解决方案相比,可能无法最优地运行此语句。
如您所请求,使用内连接:
// I'm assuming DISTINCT is required here, as you
// - are not interested in TABLE_B and TABLE_C results (semi join semantics)
// - do not want any duplicate TABLE_A values
create.selectDistinct(TABLE_A.fields())
      .from(
          isFooSearched
        ? TABLE_A
             .join(TABLE_B).onKey(FK_TABLEA_TABLEB)
             .join(TABLE_C).onKey(FK_TABLEB_TABLEC)
          )
        : TABLE_A)
      .where(
          isFooSearched
        ? TABLE_C.FIELDC.containsIgnoreCase("foo")
        : trueCondition())
      .fetch();

我在这里做了一些假设,包括您的联接查询中使用DISTINCT可能是正确的,但它可能会对您的“默认”查询变体造成影响,因此,将其硬塞到单个动态查询中可能过于复杂。

因此...

使用两个不同的查询

对我来说,这两个查询足够简单,可以允许一些重复,并根据标志运行两个不同的查询:

if (isFooSearched)
    create.select().from(TABLE_A) /* joins or semi joins here */ .fetch();
else
    create.select().from(TABLE_A).fetch();

侧记

所有解决方案都假定您在代码中使用了这些静态导入:

import static org.jooq.impl.DSL.*;

谢谢Lukas!你是对的,这两个查询很简单。但不幸的是,我不仅有fooParam要检查。(还要感谢您的出色工作!Jooq太棒了!) - Luis C.
@Luigi1982:感谢您的赞美之词。当然,我有点“担心”您的示例可能会被简化,所以我想半连接解决方案最适合这里... - Lukas Eder

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接