【问题标题】:Use Mapstruct as RecordMapper for JOOQ使用 Mapstruct 作为 JOOQ 的 RecordMapper
【发布时间】:2020-07-18 07:47:49
【问题描述】:

我想实现我自己的RecordMapper 并使用 Mapstruct 将 Record 映射到 POJO。我不太明白如何做到这一点。我关注了这部分文档:https://www.jooq.org/doc/3.13/manual/sql-execution/fetching/pojos-with-recordmapper-provider/

我的映射器如下所示:

public class LanguageMapper<R extends Record, E> implements RecordMapper<R, Language> {

  @Override
  public Language map(R record) {
    LanguageRecord languageRecord = (LanguageRecord) record;

    // this is just an example, in the future this is the kind of mapping that would be performed automatically via mapstruct
    return new Language(
             languageRecord.getId(), 
             languageRecord.getNamespaceId(), 
             languageRecord.getLanguage(), 
             languageRecord.getCountryCode(), 
             languageRecord.getLanguageTag()
    );
  }
}

问题在于,作为record,我实际上并没有得到LanguageRecord,而是我的语言表的RecordImpl,因此无法将record 转换为LanguageRecord。知道我需要改变什么吗?

使用RecordImpl 时有趣的是,如果我做这样的事情

record.get(LANGUAGE.LANGUAGE_TAG);

它已经获得了错误的信息(它正在获得 LANGUAGE.NAMESPACE_ID)。因此,当这样获取它然后将其映射到 POJO 时,它也是错误的。

(根据这个问题POJO Mapping in JOOQ regardless of parameter order创建了这个问题)

【问题讨论】:

  • 1) 我不确定 MapStruct 与您的问题有何关联。 2) 你已经回答了你不能投的部分。 RecordMapperProvider所有 RecordMapper 实例的通用全局 提供程序,而不仅仅是您对单个查询执行感兴趣的实例。到目前为止,您在问题中提出的事实无法回答您获得错误数据的原因。我可以推荐阅读本指南:stackoverflow.com/help/minimal-reproducible-example。到目前为止,很难看到您正在尝试做什么以及您的问题到底是什么失败了
  • 抱歉 Lukas,我进行了一些挖掘,结果发现我遇到的问题只是由于执行带有星号的选择而不是指定单个字段而引起的。一旦我指定了字段,POJO 映射就可以正常工作。我的问题现在解决了。
  • 使用显式星号将按照它们在 SQL 表中定义的顺序生成列。如果生成的代码与 SQL 表不同步,则生成的顺序可能不正确,因此 jOOQ 会期望不同的顺序...

标签: java database mapping record jooq


【解决方案1】:

目前不支持映射源和目标的泛型: https://github.com/mapstruct/mapstruct/issues/583

示例解决方法:

https://github.com/mapstruct/mapstruct/issues/631

定义映射器时需要使用具体的类。

【讨论】:

    【解决方案2】:

    问题是此处描述的问题的结果:POJO Mapping in JOOQ regardless of parameter order

    但事实证明,甚至不需要任何类型的映射器就可以解决问题。

    问题: 如果 JOOQ 生成 POJO/记录/等。基于数据库,该数据库具有一定顺序的表属性,但是在 JOOQ 已经生成 POJO/Records/etc 之后属性的顺序发生了变化。 SELECT * 可能不会将字段映射到 POJO 中的正确属性

    例如POJO Language 具有属性countrylanguage,突然Language 包含Lanugage.getLanguage() 中的country 的表值和Language.getCountry() 中的lanugage 的表值。

    这个问题可以通过在SELECT-statement 中指定一个顺序(不管数据库字段的实际顺序是什么)来解决,比如SELECT language, country

    【讨论】:

      猜你喜欢
      • 2020-06-11
      • 1970-01-01
      • 1970-01-01
      • 2016-12-28
      • 2020-06-16
      • 1970-01-01
      • 2019-03-27
      • 2021-06-26
      • 1970-01-01
      相关资源
      最近更新 更多