使用Mapstruct作为JOOQ的RecordMapper。

huangapple go评论90阅读模式
英文:

Use Mapstruct as RecordMapper for JOOQ

问题

我想实现自己的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;

    // 这只是一个示例,将来这种映射将通过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,结果也会是错误的。

(根据这个问题创建了这个问题https://stackoverflow.com/questions/60926102/pojo-mapping-in-jooq-regardless-of-parameter-order)

英文:

I would like to implement my own RecordMapper and use Mapstruct to map the Record to the POJO. I don't quite understand how to accomplish this. I followed this part of the docs: https://www.jooq.org/doc/3.13/manual/sql-execution/fetching/pojos-with-recordmapper-provider/

My mapper looks like this:

public class LanguageMapper&lt;R extends Record, E&gt; implements RecordMapper&lt;R, Language&gt; {

  @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()
    );
  }
}

The issue is that as a record I'm not actually getting a LanguageRecord but a RecordImpl of my language table and can thus not cast record to LanguageRecord. Any idea what I need to change?

What's interesting when using the RecordImpl is, if I do something like this

record.get(LANGUAGE.LANGUAGE_TAG);

It will already get the wrong information (it's getting the LANGUAGE.NAMESPACE_ID). Thus when getting it like this and then mapping it to the POJO it will be wrong as well.

(Created this question based on this question https://stackoverflow.com/questions/60926102/pojo-mapping-in-jooq-regardless-of-parameter-order)

答案1

得分: 0

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

示例解决方法:

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

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

英文:

There is no support for Generics for mapping source and target as of now :
https://github.com/mapstruct/mapstruct/issues/583

Example wrokaround:

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

You need to use concrete classes when defining the mapper.

答案2

得分: 0

问题是这里描述的问题的结果:https://stackoverflow.com/questions/60926102/pojo-mapping-in-jooq-regardless-of-parameter-order

但事实证明,甚至可以在不需要任何类型的映射器的情况下解决这个问题。

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

例如,POJO Language 具有属性 countrylanguage,突然之间 LanguageLanugage.getLanguage() 中包含了表值 country,而在 Language.getCountry() 中包含了表值 lanugage

可以通过在 SELECT 语句中指定顺序(不管实际的数据库字段顺序如何)来解决此问题,例如 SELECT language, country

英文:

The question was a result of the problem described here: https://stackoverflow.com/questions/60926102/pojo-mapping-in-jooq-regardless-of-parameter-order

But it turns out that the problem can be solved without even needing any sort of mapper.

Problem:
If JOOQ generates POJOs/Records/etc. based on a database which has the attributes of a table in a certain order, but the order of the attributes changes after JOOQ already generated the POJOs/Records/etc. it's possible that a SELECT * will not map the fields to the correct attributes in the POJOs

E.g. The POJO Language has the attributes country and language and suddenly Language contains the table value of country in Lanugage.getLanguage() and the table value of lanugage in Language.getCountry().

This issue can be solved by specifying an order (regardless what the actual order of the database fields are) in the SELECT-statement, like SELECT language, country.

答案3

得分: 0

我使用jOOQ codegen生成了我的Record类和POJO,我的最小映射器正常工作。

@Mapper
public interface FooMapper extends RecordMapper<FooRecord, Foo>, RecordUnmapper<Foo, FooRecord> {
}

它会警告未映射的字段,但您可以通过以下方式进行抑制。

@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
英文:

I generated my Record classes and POJOs with jOOQ codegen and my minimal mapper just worked

@Mapper
public interface FooMapper extends RecordMapper&lt;FooRecord, Foo&gt;, RecordUnmapper&lt;Foo, FooRecord&gt; {
}

It warns about unmapped fields, but you can suppress that with.

@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)

huangapple
  • 本文由 发表于 2020年4月6日 18:25:36
  • 转载请务必保留本文链接:https://go.coder-hub.com/61057659.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定