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

java MapStruct-在相关集合中映射字段

班凌
2023-03-14
public class Employee {
    private Integer id;
    private String name;
    private Set<Phone> phones;
}

public class Phone {
    private Integer id;
    private String number;
}
public class EmployeeDto {
    private Integer id;
    private String name;
    private Set<PhoneDto> phones;
}

public class PhoneDto {
    private Integer id;
    private String num;
}

最后,我在我的映射类中使用了这个方法:

@Mappings({
        @Mapping(target = "num", source = "phones.number")
})
public abstract List<EmployeeDto> toEmployeeDtoList(List<Employee> employeeList);

但这返回给我java:当我想编译时,源参数中不存在名为“phones.number”的属性。。我知道我的代码有问题,但我找不到适合我需要的有用的东西。你能帮我解决这个问题吗?

共有1个答案

金宣
2023-03-14

第一个原因:在指定collection->collection映射(phonedto->Phone,employeedto->Employee)之前,应该指定Object->Object映射,因为mapstruct嵌套表示法不能扩展到集合中。从我的角度来看,您不需要在映射器中保存基本的集合映射。你总能做到:

employees.stream()
        .map(mapper::toDto)
        .collect(Collectors.toList());

注意:但是如果您需要嵌套集合上的一些特定的集合->collection映射,您应该指定它。(在您的示例中,可能使用下面的LinkedHashSet对集合进行排序,如果不指定collection->collection mapping,就会丢失排序,因为mapstruct将使用HashSet作为Set ->Set 转换的默认实现)。

如果映射器可以访问映射,Mapstruct将选择所有映射链(嵌套类映射器应该在同一个类中,或者在@mapper(uses=类注释中声明)。

第二个原因:您的@mapping(target=“num”,source=“phones.number”)<<--不能工作,因为它不知道应该从phones集合中的哪个元素检索number。就像您试图编写employeedto.num(单记录)=emloyee.phones(多记录).number(单记录)一样。

IMHO块:使用mapstruct的最佳实践是使用干净的接口。这表明您在实体/dto/view/model/等中具有清晰透明的结构和良好的关系。如果需要更具体的内容-您总是可以使用@aftermapping@beforemapping注释指定默认方法。或者转到抽象类实现/decorator(@decoratedWith映射)。

对于这种情况有一些肮脏的黑客行为--@mapping(target=“num”,expression=“java(your_java_code_as_string_in_here)”),但请注意:该表达式是一个字符串,只有在创建映射器时才会失败,在所有类型的重构中都不起作用。

这是模型的示例映射(以两种方式):

@Mapper
public interface EmployeeMapper {

  Employee toEmployee(EmployeeDto employeeDto);

  EmployeeDto toEmployeeDto(Employee employee);

  @Mapping(target="number", source="num")
  Phone toPhone(PhoneDto phoneDto);

  @InheritInverseConfiguration
  PhoneDto toPhoneDto(Phone phone);

  List<EmployeeDto> toEmployeeDtoList(List<Employee> employeeList);
}

也可以考虑一个很好的实践--每个逻辑对象对都有不同的映射器。

@Mapper(uses = {PhoneMapper.class, OtherMapper.class}) // this is class level annotation.
 类似资料:
  • 主要内容:集合类型,以下是纠正/补充内容:集合(Collection)是一个将多个对象分组为一个单元的java框架。它用于存储,检索和操作汇总数据。 在JPA中,可以使用集合来持久化包装类和String的对象。JPA允许三种对象存储在映射集合中 - 基本类型,实体和嵌入式类型。 集合类型 根据要求,我们可以使用不同类型的集合来持久化对象。如下所示 - List Set Map 包中包含集合框架的所有类和接口。 以下是纠正/补充内容: 根据

  • 主要内容:集合映射实例,程序输出结果集合(Set)是一个包含唯一元素的接口。 这些元素不保留任何顺序。当需要以无序方式检索唯一元素时,可以使用。 完整的项目目录结构如下所示 - 集合映射实例 在这个例子中,我们将一个对象嵌入到一个实体类中,并将其定义为一个集合类型 - 。 这个例子包含以下步骤 - 第1步: 在包下创建一个实体类,这个类包含员工, 和嵌入对象(员工地址)。注解 表示嵌入对象。 文件:Employee.java 的代码

  • 你可以定义一个新的名或从下拉式菜单中选择导入到现有的表或集合。 【注意】如果你在“目标表”或“目标集合”输入一个新的名,在“是新的”内的框将会自动显示为“是”。 导入多个表或集合时,所有表或集合会显示在列表中。

  • 问题内容: 欢迎, Hibernate映射存在一些问题。 数据库结构: POJO结构: 我想拥有的是TableC Pojo映射中TableB元素的集合,映射键是tableA。 该集合应该是只读的。 映射应为hbm而非注释。 我可能已经以各种可能的方式完成了此操作…我遇到的关闭情况是,当我对一个TableC对象进行操作时,一切都是正确的,但是如果我加载它们的集合,则只有最后一个具有正确的集合集。 更

  • 我可以想象这样一个解决方案:一个子映射器,在这个映射器中,我用如下所示的查找重写Dto to Domain方法: 但目标在MapStruct中是必需的。也许我可以以某种方式指定整个对象作为目标?

  • 我是使用dozer的新手。我需要将集合映射到一个类,该类是集合中源类的属性。我有如下类技术 我想映射到 哪里 我的推土机绘图将是什么样子?