mapstruct 映射实体 OneToMany 到 DTO 和反向
mapstruct mapping Entity OneToMany to DTO and reverse
我正在尝试使用 mapstruct,我需要将 Entity
映射到子 Entity
列表,我有关系 oneToMany
和 manyToOne
我需要在这两种情况下进行映射:
@Data
@Entity
public class EmailEntity {
private int id;
... // some fields
@ManyToOne
private DeliveredEmailInfoEntity deliveredEmailInfo;
}
.
@Data
@Entity
public class DeliveredEmailInfoEntity {
private int id;
... // some fields
@OneToMany
private List<EmailEntity> emails;
}
映射到:
@Data
public class EmailDTO {
private int id;
... // some fields
private DeliveredEmailInfoDTO deliveredEmailInfo;
}
.
@Data
public class DeliveredEmailInfoDTO {
private int id;
... // some fields
private List<EmailDTO> emails;
}
如何以最佳方式做到这一点?
(另见其他答案)
应该很简单,你的情况没有什么挑战:
@Mapper
public interface EmailInfoMapper {
EmailDTO entityToDTO(EmailEntity duration);
EmailEntity dtoToEntity(EmailDTO price);
DeliveredEmailInfoDTO entityToDTO(DeliveredEmailInfoEntity duration);
DeliveredEmailInfoEntity dtoToEntity(DeliveredEmailInfoDTO price);
}
您应该在您的问题中包括您的映射器以及您遇到的问题。
为了避免嵌套字段的无限交叉设置,您应该限制这种依赖性,例如在第二个嵌套级别上,即您的根 EmailDTO
将有一个嵌套的 DeliveredEmailInfoDTO
对象(多对-一个关系),而您的根 DeliveredEmailInfoDTO
将具有嵌套 EmailDTO
对象的列表(一对多关系),而在下一个嵌套级别上没有任何内容:
@Mapper(uses = DeliveredEmailInfoMapper.class)
public interface EmailMapper {
@Mapping(target = "deliveredEmailInfo.emails", ignore = true)
EmailDTO toDTO(EmailEntity entity);
// other methods omitted
@Named("emailDTOList")
default List<EmailDTO> toEmailDTOList(List<EmailEntity> source) {
return source
.stream()
.map(this::toDTO)
.peek(dto -> dto.setDeliveredEmailInfo(null))
.collect(Collectors.toList());
}
}
@Mapper(uses = EmailMapper.class)
public interface DeliveredEmailInfoMapper {
@Mapping(target = "emails", source = "emails", qualifiedByName = "emailDTOList")
DeliveredEmailInfoDTO toDTO(DeliveredEmailInfoEntity entity);
// other methods omitted
}
我正在尝试使用 mapstruct,我需要将 Entity
映射到子 Entity
列表,我有关系 oneToMany
和 manyToOne
我需要在这两种情况下进行映射:
@Data
@Entity
public class EmailEntity {
private int id;
... // some fields
@ManyToOne
private DeliveredEmailInfoEntity deliveredEmailInfo;
}
.
@Data
@Entity
public class DeliveredEmailInfoEntity {
private int id;
... // some fields
@OneToMany
private List<EmailEntity> emails;
}
映射到:
@Data
public class EmailDTO {
private int id;
... // some fields
private DeliveredEmailInfoDTO deliveredEmailInfo;
}
.
@Data
public class DeliveredEmailInfoDTO {
private int id;
... // some fields
private List<EmailDTO> emails;
}
如何以最佳方式做到这一点?
(另见其他答案)
应该很简单,你的情况没有什么挑战:
@Mapper
public interface EmailInfoMapper {
EmailDTO entityToDTO(EmailEntity duration);
EmailEntity dtoToEntity(EmailDTO price);
DeliveredEmailInfoDTO entityToDTO(DeliveredEmailInfoEntity duration);
DeliveredEmailInfoEntity dtoToEntity(DeliveredEmailInfoDTO price);
}
您应该在您的问题中包括您的映射器以及您遇到的问题。
为了避免嵌套字段的无限交叉设置,您应该限制这种依赖性,例如在第二个嵌套级别上,即您的根 EmailDTO
将有一个嵌套的 DeliveredEmailInfoDTO
对象(多对-一个关系),而您的根 DeliveredEmailInfoDTO
将具有嵌套 EmailDTO
对象的列表(一对多关系),而在下一个嵌套级别上没有任何内容:
@Mapper(uses = DeliveredEmailInfoMapper.class)
public interface EmailMapper {
@Mapping(target = "deliveredEmailInfo.emails", ignore = true)
EmailDTO toDTO(EmailEntity entity);
// other methods omitted
@Named("emailDTOList")
default List<EmailDTO> toEmailDTOList(List<EmailEntity> source) {
return source
.stream()
.map(this::toDTO)
.peek(dto -> dto.setDeliveredEmailInfo(null))
.collect(Collectors.toList());
}
}
@Mapper(uses = EmailMapper.class)
public interface DeliveredEmailInfoMapper {
@Mapping(target = "emails", source = "emails", qualifiedByName = "emailDTOList")
DeliveredEmailInfoDTO toDTO(DeliveredEmailInfoEntity entity);
// other methods omitted
}