当前位置: 首页 > 知识库问答 >
问题:

Mapstruct:在id上加入

谢雅珺
2023-03-14

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

试图将其分解为一个简化的案例,我想出了一个例子:

>

在商业领域,学校只有一个教师名单,每个教师都持有一份他们课程的名单。

类图:UML:DTO/Domain

最初,我希望用mapstruct语法解决这个问题,比如在Foreignd和teacher id上加入一个连接(或通过关联限定),伪代码如下:

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

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

共有1个答案

姜杜吟
2023-03-14

我怀疑您是否可以在没有后续映射的情况下执行此操作。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时

如果您需要多次查询,您可以创建一个自己的类作为上下文,例如有自己的方法通过教师ID查找所有课程。

 类似资料:
  • 我最近开始使用mapstruct,在编码时我坚持使用一个场景。为了解决下面默认方法之间的模糊性,我试图在列表中使用“限定由” 但是第1行显示错误,因为需要指定“target”。我不确定这里的目标应该是什么,因为Line是一个集合对象。即使我不使用@mapping,mapstuct也会生成mapper实现。我阅读了mapstuct文档,但对这个场景了解不多。如何在列表上使用命名注释来明确表示这是要使

  • 我有一个对象,其中包含几个列表。有没有一种方法来克隆这个对象,没有id使用mapstruct,即使是嵌套的对象列表,以自动的方式能够持久化它。 实际制图员 有没有一种方法可以忽略所有id,而不必对每个列表进行@Mapping(target=“id”,ignore=true)?

  • 我尝试将DTO对象映射到JPA实体。我在我的父母实体中有一个孩子的集合。可以添加它们。Mapstruct通过(http://mapstruct.org/documentation/dev/reference/html/#collection-映射策略)。 如果我创建了新实体,但在添加新子实体之前,无法在更新时清除子实体,则此操作可以正常工作。 Mapstruct手册说(http://mapstru

  • 我有一份谷歌学者论文的作者名单:。我想摘录并打印至少3篇论文的标题。 您可以使用学术词典从每位作者处获取论文信息: 输出看起来像(只是从一个作者那里得到的一小部分摘录) 我如何收集四个作者中有三个或更多的论文的,特别是? 编辑:事实上,有人指出,对每一篇论文都不是唯一的,我错了。最好只使用本身

  • 我在我的项目中使用Mapstruct。在其中一个实体中,我有set[oneToMany]结构。当我在存储库中使用findAll()检索所有数据时,如果没有绑定,则返回一个空的HashSet。

  • 我有一个用并尝试使用注释。该方法还用注释。将忽略注释。是否可以在Mapstruct方法上使用?