gpt4 book ai didi

mapstruct - 如何将嵌套引用展平为一个简单的目标?

转载 作者:行者123 更新时间:2023-12-05 04:02:12 27 4
gpt4 key购买 nike

我在 MapStruct 中使用 spring data jdbc。 POJO 与具有所有“仅限内部”数据(如代理键、审计信息等)的表结构保持一致,而域对象是分层的并且仅包含业务相关数据。我必须在特定于表的 POJO(平面结构)和具有嵌套对象的域对象之间进行映射。我怎样才能最好地使用 MapStruct 1.2.0 做到这一点?

// Pojo for table
public class PersonsRecord {
@Id
private Integer surrogateKey; // should not be mapped

private String loginId;
private String name;
private Timestamp memberSince;

// address columns
private Integer houseNumber;
private String addressStreet;
private String addressCity;
private String country;

// getters and setters
}

// Domain object
public class PersonDto {
private String loginId;
private String name;
private Timestamp memberSince;

private Address address;
}

@Mapper(uses = MapperUtils.class)
public interface PersonMapper {

PersonDto toPersonDto(PersonRecord person);

Address toAddress(PersonRecord person);
}

toPersonDto 生成的代码会忽略 Address 并且不会像 MapStruct 引用那样调用 toAddress 方法提及。可能是因为这两种方法采用相同的输入类型? toAddress 的生成代码看起来不错。只是它不会由 MapStruct 生成自动连接。

反向映射生成类似。没有自动调用。

有没有办法让它自动(没有自定义方法或装饰器等)?我在很多地方都有类似的模式。

注意:MapperUtils 用于实例化具有不可变字段的 DTO。

更新:我使用 Filip 的答案将 PersonRecord 映射到 PersonDto,包括 Person.Address .对于反向映射,我做了以下操作:

@Mapper(uses = MapperUtils.class)
public abstract class PersonMapper {
@Mapping(target = "address", source = "person")
public abstract PersonDto toPersonDto(PersonRecord person);

protected abstract Address toAddress(PersonRecord person);

public abstract PersonRecord toRecord(PersonDto dto);

public abstract void updateAddress(PersonDto dto, @MappingTarget PersonRecord person);

@AfterMapping
protected void updateAddress(PersonDto dto, @MappingTarget PersonRecord record) {
updateAddress(dto, record);
}
}

这没有问题。感谢 Filip 提供指导。

最佳答案

toAddress方法没有被拾取的原因是MapStruct不知道它需要将toPersonDto参数映射到PersonDto.address 。您也很可能会收到地址未映射的警告。

为了进行映射,您需要告诉 MapStruct 如何映射地址。您可以使用 @Mapping 来做到这一点。你的映射器将看起来像

@Mapper(uses = MapperUtils.class)
public interface PersonMapper {

@Mapping(target = "address", source = "person")
PersonDto toPersonDto(PersonRecord person);

Address toAddress(PersonRecord person);
}

更新我忘了添加如何执行反向。

执行反向映射的一种方法是使用自定义 @Mapping 注释,您必须为 Address 中的每个条目执行此操作。这有点麻烦。有一个开放的 MapStruct Pull Request 可以更轻松地完成此映射。公共(public)关系是 mapstruct/mapstruct#1686 .

另一种方法是使用多源参数映射。这看起来像:

@Mapper(uses = MapperUtils.class)
public interface PersonRecordMapper {

default PersonRecord toPersonRecord(PersonDto personDto) {
if (personDto == null) {
return null;
}

return toPersonRecord(personDto, personDto.getAddress());
}

@Mapping(target = "surrogateKey", ignore = true)
PersonRecord toPersonRecord(PersonDto personDto, Address address);

}

当且仅当 Address 中的名称属性与 PersonRecord 中的名称属性匹配时,这将在没有手动 @Mapping 的情况下工作。否则,您仍然需要定义 @Mapping

关于mapstruct - 如何将嵌套引用展平为一个简单的目标?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54580824/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com