英文:
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<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()
);
}
}
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
具有属性 country
和 language
,突然之间 Language
在 Lanugage.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<FooRecord, Foo>, RecordUnmapper<Foo, FooRecord> {
}
It warns about unmapped fields, but you can suppress that with.
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论