命名和类型安全的相关子查询

Named and typesafe correlated subquery

我正在使用 JOOQ v3.14.3 并尝试使用相关子查询执行简单的 select。以抽象的方式:

Field<?> subquery = DSL.select(MY_TABLE.TIMESTAMP_FIELD)
        .from(MY_TABLE)
        .where(...)
        .asField("timestamp");

var mainQuery = create.select(OTHER_TABLE.SOME_FIELD, subquery)....;

我的问题是,子查询保证 return OffsetDateTime 值,但在生成的记录中我只能使用纯字符串 "timestamp" 访问这些值并且有像

那样进行手动转换
OffsetDateTime timestamp = (OffsetDateTime) record.get("timestamp");

可以像这样创建类型安全的 Field

Field<OffsetDateTime> subquery = DSL.field(DSL.select(MY_TABLE.TIMESTAMP_FIELD)
        .from(MY_TABLE)
        .where(...));

但是这个字段似乎没有名字,所以我不能轻易地从结果记录中检索它。我的子查询不是常量,所以我每次都必须重新创建它,不能简单地保留对此 Field.

的引用

我想像这样:定义一个自定义命名字段,然后在子查询和记录访问中使用它

public static final Field<OffsetDateTime> CUSTOM_TIMESTAMP_FIELD = Whatever.customField("timestamp", OffsetDateTime.class);

// ...

Field<OffsetDateTime> subquery = DSL.select(MY_TABLE.TIMESTAMP_FIELD)
        .from(MY_TABLE)
        .where(...)
        .asField(CUSTOM_TIMESTAMP_FIELD);

// ...

OffsetDateTime timestamp = record.get(CUSTOM_TIMESTAMP_FIELD);

best/nicest 解决这个问题的方法是什么?

传递子查询引用

But this field doesn't seem to have a name so I can not easily retrieve it from the resulting Record.

你试过了吗?因为您可以只使用 subquery 引用从记录中检索值:

OffsetDateTime value = record.get(subquery)

当然,您可能更愿意像这样为子查询设置别名:

Field<OffsetDateTime> subquery = DSL.field(DSL.select(MY_TABLE.TIMESTAMP_FIELD)
        .from(MY_TABLE)
        .where(...))
        .as("subquery");

但是,您仍然会使用该引用来获取所需的值。

为子查询名称使用全局变量

您正在寻找的方法可以这样实现:

public static final Field<OffsetDateTime> CUSTOM_TIMESTAMP_FIELD = 
    DSL.field(DSL.name("timestamp"), OffsetDateTime.class);

您现在可以将子查询重命名为它:

Field<OffsetDateTime> subquery = DSL.field(DSL.select(MY_TABLE.TIMESTAMP_FIELD)
        .from(MY_TABLE)
        .where(...))
        .as(CUSTOM_TIMESTAMP_FIELD);

然后在您的记录访问中重复使用该名称:

OffsetDateTime value = record.get(CUSTOM_TIMESTAMP_FIELD)