4

如何编写 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”子句加入字段?

4

2 回答 2

4

虽然我当然同意颤振的答案是一个更理想的解决方案路径,但我会快速添加一个回答您特定编译错误问题的响应。

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

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>,这是无效的。

因此,解决方案是编写:

// 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>)如果您正在使用自定义数据类型绑定/转换器。

于 2017-06-12T07:57:09.280 回答
2

先声明 CTE 怎么样? 显式公用表表达式

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<?>FieldTable

于 2017-06-11T16:26:18.383 回答