首页 > 解决方案 > jOOQ - 将运行时映射与手动创建的字段一起使用

问题描述

在我的项目中,我有一个有问题的表(PROBLEMATIC此处命名),其中包含一些始终存在的列(在架构中定义,例如:)id,并且在应用程序工作时动态添加或删除其他列。Field我可以通过一个返回适当对象的简单函数来使用这些“动态”列:

public static <T> Field<T> getField(String fieldName, Class<T> type) {
  return DSL.field(DSL.name(PROBLEMATIC.getName(), fieldName), type);
}

Field该函数运行良好,我可以使用它返回的对象创建 jOOQ 查询。

当我想添加一个运行时映射时,问题就开始了,该映射将在呈现的查询中重命名这个有问题的表。

Settings settings = new Settings()
    .withRenderSchema(false)
    .withRenderNameStyle(RenderNameStyle.QUOTED)
    .withRenderCatalog(false)
    .withRenderMapping(new RenderMapping()
        .withSchemata(new MappedSchema()
            .withInput("PUBLIC")
            .withTables(
                new MappedTable().withInput("problematic").withOutput("another_problematic")
            )
        ));

当我使用 jOOQ 创建一个简单的查询时,映射部分起作用。

dsl.select(PROBLEMATIC.ID, getField("dynamic1", String.class), getField("dynamic2", String.class))
   .from(PROBLEMATIC)
   .fetch();

渲染查询:

select "another_problematic"."id", "problematic"."dynamic1", "problematic"."dynamic2" from "another_problematic"

FROM问题是:jOOQ 正确替换了在模式和子句中定义的那些列的表名。使用该方法创建的列的字段DSL.field()不受影响。

在这种情况下如何使用运行时映射?

标签: javasqljooq

解决方案


这是 jOOQ 中的一个错误:https ://github.com/jOOQ/jOOQ/issues/8991 。至少,它是用于DSL.field(Name)产生合格字段引用的调用。

一种解决方法是直接从您的PROBLEMATIC表中取消引用该列,例如

public static <T> Field<T> field(String fieldName, Class<T> type) {
    return PROBLEMATIC.field(fieldName, type);
}

请注意,为免生疑问:DSL.field(String, Class<?>)调用是普通 SQL API的一部分。那里也可能有任何表达式,包括field("a + b"). 由于 jOOQ 不解析这些表达式,因此不可能在那里应用模式映射。我知道你没有这样做,但其他人可能正在阅读这个问题。


推荐阅读