web-dev-qa-db-ja.com

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;
}

MapStructを使用して、XmlScheduleSchedulePayloadにマップするマッパーを作成しました。 「ビジネス」「ロジック」のため、notificationPeriodschedulePeriodLecturestartendのフィールド値に制限する必要があります。別のクラスを使用して、これが私が思いついたものです:

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

}

これを別の方法(つまり、別のマッパー、デコレーターなど)で実現できる方法はありますか?複数の値(xmlSchedule、講義)をマッパーに渡すにはどうすればよいですか?

6
giannoug

できることは、_@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(..);
    }
}
_

または、_@AfterMapping_メソッドを@Mapper(uses = ..)で参照される別のクラスに配置するか、デコレータを使用できます(MapStructが提供するメカニズム、または依存性注入フレームワークを使用している場合はそれを使用) 。

13
agudian