简体   繁体   English

JOOQ查询以JOIN ON WITH子句

[英]JOOQ query to JOIN ON WITH clause

How can I write a JOOQ query to join on a field from a "with" clause? 如何编写JOOQ查询以加入“ with”子句中的字段?

For example, I've tried: 例如,我尝试过:

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

However, as the compiler doesn't know the type of tableByName("a").field("x") it cannot resolve which eq() method to use. 但是,由于编译器不知道tableByName(“ a”)。field(“ x”)的类型,因此无法解析要使用的eq()方法。 Given that I know the type, is there a way I can provide it explicitly? 既然我知道类型,有没有办法可以明确地提供它? Or is there another approach I should take to join on a field from a "with" clause? 还是我应该采用另一种方法来加入“ with”子句中的字段?

While I certainly agree with flutter's answer being a more desireable path to a solution here, I'll just quickly add a response that answers your specific compilation error question. 我当然同意flutter的回答是在这里找到解决方案的更理想的途径 ,但是我将快速添加一个回答,以回答您的特定编译错误问题。

There are three things that are wrong with your current join predicate: 当前的连接谓词有三件事是错误的:

ANOTHER_TABLE.ID.eq(tableByName("a").field("x"))
  1. DSL.tableByName() is deprecated. DSL.tableByName()已弃用。 It is generally recommended to use table(Name) instead. 通常建议改用table(Name)
  2. Such a dynamically constructed Table does not know of any of its field() references, thus table(name("a")).field("x") will return null 这种动态构造的Table不知道其任何field()引用,因此table(name("a")).field("x")将返回null
  3. The compilation error is due to your ID reference being of type Field<Integer> (probably), and thus the Field.eq() method expects a Field<Integer> argument as well. 编译错误是由于您的ID引用的类型为Field<Integer> (可能),因此Field.eq()方法也期望使用Field<Integer>参数。 Without any knowledge about the type of your field "x" , the jOOQ API / Java compiler infers Field<Object> , which is invalid. 在不了解字段"x"的类型的情况下,jOOQ API / Java编译器将推断Field<Object> ,这是无效的。

So, the solution would be to write: 因此,解决方案是编写:

// 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()))

Ie to use DSL.field(Name, Class<T>) , or DSL.field(Name, DataType<T>) if you're using custom data type bindings / converters. 即如果使用自定义数据类型绑定/转换器,则使用DSL.field(Name, Class<T>)DSL.field(Name, DataType<T>)

What about declaring the CTE first? 首先宣布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();

If this does not work, you can always get the DataType<?> or the Class<?> via the Field , which you can get via the Table . 如果这不起作用,则始终可以通过Field获取DataType<?>Class<?> ,而可以通过Table获取。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM