当前位置: 首页 > 知识库问答 >
问题:

jOOQ-使用手动创建字段的运行时映射

那安宁
2023-03-14

在我的项目中,我有一个有问题的表(这里名为problemble),其中包含一些始终存在的列(在模式中定义,例如:id),当应用程序运行时,会动态添加或删除其他列。我可以通过一个简单的函数使用这些“动态”列,该函数返回适当的字段对象:

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

该函数运行良好,我可以使用它返回字段对象创建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"

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

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

共有2个答案

田兴旺
2023-03-14

昨天我想出了一个可能对其他人有帮助的解决办法

这个解决方案添加了字段,但不删除它们,没有任何方法允许这种操作(很明显,为什么要从表中删除字段?)。在我的例子中,这不是问题,因为如果动态模式发生变化,应用程序无论如何都会重新启动,但是如果你经常在不重新启动的情况下损坏你的表,持有所有这些字段的类将开始不受控制地增长。

我发现我可以使用抽象表。createField()方法,并正确映射使用该方法创建的字段。jOOQ生成的表类也使用相同的方法初始化它们的字段。因为这个方法是受保护的,所以必须创建一个扩展类,它是带有动态字段的类的包装器(problem,在我的例子中)。

public class DynamicProblematic extends Problematic {
    public static final DynamicProblematic DYNAMIC_PROBLEMATIC = new DynamicProblematic();

    private Map<String, TableField<ProblematicRecord, ?>> dynamicFields = new HashMap<>();

    public <T> TableField<ProblematicRecord, T> dynamicField(String fieldName, Class<T> type) {
        if (!dynamicFields.containsKey(fieldName)) {
            if (Integer.class.isAssignableFrom(type)) {
              dynamicFields.put(fieldName, createField(fieldName, SQLDataType.INTEGER, this, ""));
            } else {
              dynamicFields.put(fieldName, createField(fieldName, SQLDataType.CLOB, this, ""));
            }
        }

        return (TableField<ProblematicRecord, T>) dynamicFields.get(fieldName);
    }
}

dynamicproblem。dynamicField()方法可以根据您的需要进行相应的实现。我需要一个接受字段名和类型的方法,在我的例子中可能是整数或字符串,我不希望传递另一个类型,所以这是令人满意的。

我决定将创建的字段存储在HashMap中并重用它们,因为每次调用AbstractTable.createField()最终都会将创建的字段添加到表实例中,并且每次调用

我不接受我的答案作为答案,因为这不是我最终需要的。

施超
2023-03-14

这是jOOQ中的一个bug:https://github.com/jOOQ/jOOQ/issues/8991.至少,它适用于DSL。字段(名称)调用,它生成合格的字段引用。

解决方法是直接从有问题的表中取消对列的引用,例如:。

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

请注意,为了避免疑问:DSL。字段(字符串,类)

 类似资料:
  • 我的团队拥有一个非回归测试项目。在这个项目中,有代码和非回归测试。像经典项目一样,我们希望使用linter或其他工具分析我们的代码。但是我们不想在每个分支上为每个提交运行测试,它们持续数小时。我们希望手动启动这些测试。 要专门在master上运行测试,我们在Jenkinsfile中包含以下内容: 但是一旦我们将我们的分支合并到master中,就会触发一个基于master的构建并启动测试。 为了避免

  • 背景和问题 我们使用包含元数据的文件来描述存储在csv文件中的数据。元数据文件包含最初从中导出数据的表的结构。我们使用jooq(pro版本)为临时表生成create语句,其中加载了csv文件中的数据。生成的ddl随后由pl/sql包执行。 这通常可以正常工作,但oracle原始字段存在问题。我不知道如何创建包含oracle RAW的表,因为SQLDataType不包含RAW。 简化的可运行示例 这

  • 我正在使用JOOQ(JOOQ中的新手)在spring boot项目中使用Rest API在运行时创建数据库。在其中一种情况下,我需要创建一个具有复合主键的表,该主键可以是多个列的组合。我使用下面的代码创建约束- 我已经有

  • 我有一张表,一列是UDT 表中该部分的ES映射: 索引失败,原因是: 类型:mapper_parsing_exception,原因:执行查询失败:空:字段internal_changed与类型日期不匹配类型时间戳,caused_by:{类型:invalid_request_exception,原因:字段internal_changed与类型日期不匹配类型时间戳} 我做错了什么?

  • jOOQ具有文档中所述的CREATE TABLE语法: 我想知道如何定义哪个列属于主键?那么,在jOOQ中有没有办法用主键信息创建create TABLE语句呢? 我对SQLite的解决方案特别感兴趣,它没有语法来添加主键,所以我认为在最坏的情况下,我必须去一个特定于数据库的解决方案?

  • 问题内容: 我在尝试了解如何在Django中创建动态选择字段时遇到了一些麻烦。我有一个模型设置类似: 我想做的是创建一个选择字段whos的值是与该骑手相关联的航点(将是登录的人)。 目前,我以如下形式覆盖init: 但是所有要做的就是列出所有路标,它们与任何特定的骑手都没有关联。有任何想法吗?谢谢。 问题答案: 你可以通过将用户传递给表单init来过滤航点 启动表单时从你的角度来看 在模型形式的情