我正在使用Mapstruct从生成的DTO (metro,xsd)映射到我们的业务域对象。我的困难在于DTO实际上并不引用子对象,而是使用ID来引用相关的实例。
为了将其分解为一个简化的案例,我想出了一个例子:
teacherId在每门课程中引用。最初,我希望用mapstruct语法来解决这个问题,比如foreignId上的联接和教师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的映射中,正确/打算用什么方式来解决这些类型的“联接”?
发布于 2018-07-11 20:58:05
我怀疑没有@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 );
}
}(当使用>= 8时,可以使用带有默认方法的接口)
如果您需要多次查询,您可以创建自己的类作为上下文,例如,它有自己的方法通过教师ID查找所有课程。
https://stackoverflow.com/questions/51280962
复制相似问题