我正在使用Mapstruct将生成的DTO(地铁,xsd)映射到我们的业务域对象。我的困难在于,DTO实际上并未引用子对象,而是使用ID来引用关联的实例。

为了简化为一个简单的案例,我举了一个例子:


SchoolDTO列出了教师和课程列表。一个老师
在每个课程中只能通过teacherId引用该课程。
在商业领域,学校只有一个老师列表,每个老师
持有他们的课程清单。


类图:UML: DTO / Domain

最初,我希望通过mapstruct语法解决此问题,例如对foreignId和Teacher ID(或某些qualifiedBy关联)的联接,伪代码如下:

@Mapping(source="courses", target="teachers.courses", where="teacher.id = course.teacherId")


DTO:

public class SchoolDto {
    List<TeacherDto> teachers;
    List<CourseDto> courses;
}

public class TeacherDto {
    String id;
    String name;
}

public class CourseDto {
    String name;
    String teacherId;
}


域:

public class School {
    List<Teacher> teachers;
}

public class Teacher {
    String name;
    List<Course> courses;
}

public class Course {
    String name;
}


我现在正在使用相当大的@AfterMapping方法来解决它,但是我觉得这不是一个特殊的用例-所以也许我缺少了一些显而易见的东西。用Mapstruct解决映射中的“连接”类型的正确/预期方法是什么?

最佳答案

我怀疑您可以在没有@AfterMapping的情况下执行此操作。 MapStruct是“仅”用于将一个对象映射到另一个对象,它不支持任何类型的查询来查找或连接数据。

如果您尚未使用它,这听起来像是使用上下文的好用例。那么@AfterMapping并不是很大:

@Mapper
public abstract class SchoolMapper {
    public School toSchool(SchoolDto school) {
        return toSchool( school, school.getCourses() );
    }

    protected abstract School toSchool(SchoolDto school, @Context List<CourseDto> courses);

    @Mapping(target = "courses", ignore = true) // see afterMappingToTeacher
    protected abstract Teacher toTeacher(TeacherDto teacher, @Context List<CourseDto> courses);

    protected abstract Course toCourse(CourseDto course);

    @AfterMapping
    void afterMappingToTeacher(@MappingTarget target, TeacherDto source, @Context List<CourseDto> courses) {
        // omitted null-checks

        List<Course> courses = new ArrayList<>();
        for(CourseDto course : courses) {
            if(course.getTeacherId().equals(source.getId())) {
                courses.add( toCourse(course) );
            }
        }

        target.setCourses( courses );
    }
}


(当使用Java> = 8时,可以使用具有默认方法的接口)

如果您需要多次查询事物,则事物可以创建一个自己的类作为上下文,例如,它具有自己的方法来按老师ID查找所有课程。

关于java - Mapstruct:加入ID,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/51280962/

10-11 08:49