使用Mapstruct将多个源字段映射到相同类型的目标字段

gia*_*oug 7 java mapping mapstruct

考虑以下POJO:

public class SchedulePayload {
    public String name;
    public String scheduler;
    public PeriodPayload notificationPeriod;
    public PeriodPayload schedulePeriod;
}

private class Lecture {
    public ZonedDateTime start;
    public ZonedDateTime end;
}

public class XmlSchedule {
    public String scheduleName;
    public String schedulerName;
    public DateTime notificationFrom;
    public DateTime notificationTo;
    public DateTime scheduleFrom;
    public DateTime scheduleTo;
}

public class PeriodPayload {
    public DateTime start;
    public DateTime finish;
}
Run Code Online (Sandbox Code Playgroud)

使用MapStruct,我创建了一个映射XmlSchedule到a 的映射器SchedulePayload.由于"业务""逻辑",我需要约束notificationPeriodschedulePeriod一个Lecture's startend字段值.以下是我使用另一个课程:

@Mapper(imports = { NotificationPeriodHelper.class })
public interface ISchedulePayloadMapper
{
    @Mappings({
        @Mapping(target = "name", source = "scheduleName"),
        @Mapping(target = "scheduler", source = "schedulerName"),
        @Mapping(target = "notificationPeriod", expression = "java(NotificationPeriodHelper.getConstrainedPeriod(xmlSchedule, notificationFrom, notificationTo))"),
        @Mapping(target = "schedulePeriod", expression = "java(NotificationPeriodHelper.getConstrainedPeriod(xmlSchedule, scheduleFrom, scheduleTo))")
    })
    SchedulePayload map(XmlSchedule xmlSchedule, Lecture lecture);

}
Run Code Online (Sandbox Code Playgroud)

有没有办法可以用另一种方式实现(即另一个映射器,装饰器等)?如何将多个值(xmlSchedule,讲座)传递给映射器?

小智 12

您可以做的是创建一种@AfterMapping手动填充这些部分的方法:

@Mapper
public abstract class SchedulePayloadMapper
{
    @Mappings({
        @Mapping(target = "name", source = "scheduleName"),
        @Mapping(target = "scheduler", source = "schedulerName"),
        @Mapping(target = "notificationPeriod", expression = "java(NotificationPeriodHelper.getConstrainedPeriod(xmlSchedule, notificationFrom, notificationTo))"),
        @Mapping(target = "schedulePeriod", expression = "java(NotificationPeriodHelper.getConstrainedPeriod(xmlSchedule, scheduleFrom, scheduleTo))")
    })
    public abstract SchedulePayload map(XmlSchedule xmlSchedule, Lecture lecture);

    @AfterMapping
    protected void addPeriods(@MappingTarget SchedulePayload result, XmlSchedule xmlSchedule, Lecture lecture) {
        result.setNotificationPeriod(..);
        result.setSchedulePeriod(..);
    }
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以将该@AfterMapping方法放在另一个引用的类中,也@Mapper(uses = ..)可以使用Decorator(使用MapStruct提供的机制,或者使用依赖注入框架).

  • 请注意,在对象中使用构建器模式时,“@MappingTarget”应该是“YourBuilder”类型,而不是您的响应类型! (3认同)