【问题标题】:Jooq select query using generated code and distinctOnJooq 使用生成的代码和 distinctOn 选择查询
【发布时间】:2021-04-12 10:10:15
【问题描述】:

我一直在使用 Jooq 生成的代码模式进行如下查询:

List<Model> results =
    dsl.selectFrom(TABLE_NAME)
       .where(TABLE_NAME.ID.eq(id))
       .fetchInto(Model.class);

这与 RecordMapperProvider 一起根据表和模型类确定使用哪个 RecordMapper:

RecordMapperProvider recordMapperProvider = new RecordMapperProvider() {
            @Override
            public <R extends Record, E> RecordMapper<R, E> provide(final RecordType<R> recordType,
                                                                    final Class<? extends E> type) {
                return (RecordMapper<R, E>) recordMappers.getOrDefault(new RecordMapperKey(recordType, type),
                                                                       new DefaultRecordMapper<>(recordType, type));
            }
        };

这是我想要完成的一个例子:

List<Model> results =
    dsl.select(TABLE_NAME.fields())
       .distinctOn(TABLE_NAME.DIFF_COL)
       .from(TABLE_NAME)
       .where(buildConditions(criteria))
       .orderBy(TABLE_NAME.PKEY_COL,
                TABLE_NAME.TS_COL.desc())
       fetchInto(Model.class);

新查询包括 distinctOn 组件,它正在更改传递给 RecordMapperProvider 的 RecordType。这个新的 RecordType 不再匹配生成的代码。

我的问题是:有没有一种解决方案可以让我在生成的代码中保留原始 RecordType 并在查询中使用 distinctOn 时仍然使用此 RecordMapperProvider 模式?

我遍历了 Jooq 库以查看如何比较 RecordType 对象,并发现它们的相等性基于查询中返回的字段集。我在想,如果我可以使用一个新的比较器来确定一个 RecordType 是否是另一个 RecordType 的子集,那么它仍然可以工作。但是,我发现带有生成代码的原始查询中的字段与使用 distinctOn 的查询中返回的内容不匹配。

【问题讨论】:

    标签: java jooq


    【解决方案1】:

    在这里找到答案:https://www.jooq.org/doc/latest/manual/sql-execution/fetching/record-vs-tablerecord/

    我能够将原始记录插入为我正在查询的表生成的 TableRecord 中:

    List<MyDisplayRecord> records =
    dsl.select(TABLE_NAME.fields())
       .distinctOn(TABLE_NAME.DIFF_COL)
       .from(TABLE_NAME)
       .where(buildConditions(criteria))
       .orderBy(TABLE_NAME.PKEY_COL,
                TABLE_NAME.TS_COL.desc())
       fetchInto(MyTable.TABLE.getRecordType());
    MyRecordMapper mapper = new MyRecordMapper();
    
    return records.stream().map(mapper::map).collect(toList());
    

    通过这种方式,我能够通过这种查询结构重用映射器。

    【讨论】:

      猜你喜欢
      • 2020-07-26
      • 2014-03-06
      • 2016-06-12
      • 2021-08-23
      • 2014-09-09
      • 2017-12-03
      • 2017-08-13
      • 2020-01-23
      • 1970-01-01
      相关资源
      最近更新 更多