JOOQ查询到JOIN ON WITH子句

时间:2017-06-11 07:16:45

标签: java sql jooq with-clause

如何编写JOOQ查询以从“with”子句加入字段?

例如,我尝试过:

create.with("a").as(select(
                           val(1).as("x"),
                           val("a").as("y")
                   ))
      .select()
      .from(tableByName("a")
      .join(ANOTHER_TABLE)
          .on(ANOTHER_TABLE.ID.eq(tableByName("a").field("x")))
      .fetch();

但是,由于编译器不知道tableByName(“a”)。field(“x”)的类型,因此无法解析使用哪个eq()方法。鉴于我知道类型,有没有一种方法可以明确地提供它?或者我是否应采取另一种方法来加入“with”子句中的字段?

2 个答案:

答案 0 :(得分:2)

虽然我当然同意flutter's answer being a more desireable path to a solution,但我会快速添加一个回答您特定编译错误问题的回复。

您当前的连接谓词有三个问题:

ANOTHER_TABLE.ID.eq(tableByName("a").field("x"))
  1. DSL.tableByName()已弃用。通常建议使用table(Name)代替。
  2. 这样一个动态构建的Table不知道其field()个引用,因此table(name("a")).field("x")将返回null
  3. 编译错误是由于您的ID引用属于Field<Integer>类型(可能),因此Field.eq()方法也需要Field<Integer>参数。在不了解您的字段类型"x"的情况下,jOOQ API / Java编译器推断Field<Object>,这是无效的。
  4. 所以,解决方案是写:

    // field(Name, Class)
    ANOTHER_TABLE.ID.eq(field(name("a", "x"), Integer.class))
    
    // field(Name, DataType)
    ANOTHER_TABLE.ID.eq(field(name("a", "x"), ANOTHER_TABLE.ID.getDataType()))
    

    即。如果您使用自定义数据类型绑定/转换器,则使用DSL.field(Name, Class<T>)DSL.field(Name, DataType<T>)

答案 1 :(得分:1)

首先宣布CTE怎么样? Explicit common table expressions

CommonTableExpression<Record2<Integer, String>> a =
  name("a").fields("x", "y").as(select(val(1), val("a")));

create.with(a)
      .select()
      .from(a)
      .join(ANOTHER_TABLE)
      .on(ANOTHER_TABLE.ID.eq(a.field("x")))
      .fetch();

如果这不起作用,您可以随时通过DataType<?>获取Class<?>Field,您可以通过Table获取。{/ p>