我正在使用Mapstruct将生成的DTO(地铁,xsd)映射到我们的业务域对象。我的困难是DTO实际上没有引用子对象,而是使用ID来引用关联的实例。
试图将其简化为一个简单的案例,我举了一个例子:
SchoolDTO列出了教师和课程列表。一个老师
每个课程中只能通过teacherId
引用该课程。
在商业领域,学校只有一个老师列表,每个老师 列出他们的课程清单。
最初,我希望以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解决映射中的“连接”类型的正确/预期方式是什么?
答案 0 :(得分:0)
我怀疑您可以在没有@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查找所有课程。