命名和类型安全的相关子查询
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)
我正在使用 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)