java - 模型映射器 - 使用自定义方法

标签 java spring-boot mapstruct modelmapper

一个 springboot 项目,我需要使用父级的指定字段和每个子级的 newest 的指定字段为仪表板 View 构建 DTO。

实体是 Plane,它与 Transponder、Maint Check 和 Transmitter 具有 OneToMany 关系。

平面

@Entity
@Data
public class Plane {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    private Long id;
    private String registration;
    @JsonIgnore
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "plane")
    private List<Transponder> listTransponder = new ArrayList<>();
    @JsonIgnore
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "plane")
    private List<Transmitter> listTransmitter = new ArrayList<>();
    @JsonIgnore
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "plane")
    private List<MaintCheck> listMaintCheck = new ArrayList<>();

转发器

@Entity
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Transponder {
    @Id
    @GeneratedValue(strategy = IDENTITY)
    private Long id;
    private String code;
    private LocalDate dateInserted;
    @ManyToOne(fetch = FetchType.LAZY, optional = true)
    private Plane plane;
}

Maint CheckTransmitter 具有带有 LocalDate 字段的类似实体。

PlaneDTO 看起来像

@Data
public class PlaneDTO {
private String registration;
private LocalDate maintCheck;      // date of most recent Maint Check
private String transponderCode;    // string of most recent Transponder code 
private Integer channel;           // Intger of most recent Transmitter Freq     
}

我试图在服务层构建这个 PlaneDTO,但我手动对 Transponder、Transmitter 和 Maint Check 列表进行了大部分排序,以从这些列表中获取最新记录。

//DRAFT METHOD CONSTRUCT DTO
@Override
public PlaneSummaryDTO getPlaneSummaryDTOById(Long id) {
  Plane Plane = this.get(id);
  PlaneSummaryDTO PlaneSummaryDTO = new PlaneSummaryDTO();
    ModelMapper mapper = new ModelMapper();
    PlaneSummaryDTO = modelMapper.map(get(id), PlaneSummaryDTO.class);
    PlaneSummaryDTO.setTRANSPONDERCode(getNewestTRANSPONDERCode(Plane));
    PlaneSummaryDTO.setLastMaintCheck(getNewestMaintCheckDate(Plane));
    PlaneSummaryDTO.setChannel(getTransmitterCode(Plane));
    PlaneSummaryDTO.setChannelOffset(getTransmitterOffset(Plane));
    return PlaneSummaryDTO;
}

// RETURN NEWEST DATE OF MAINT CHECK BY CATCH DATE
public LocalDate getNewestMaintCheckDate(Plane Plane) {
    List<MaintCheck> listMaintCheck = new ArrayList<>(Plane.getListMaintCheck());
    MaintCheck newest = listMaintCheck.stream().max(Comparator.comparing(MaintCheck::getCatchDate)).get();
    return newest.getCatchDate();
}

// RETURN NEWEST TRANSPONDER CODE FROM Plane BY DATE INSERTED
public String getNewestTransponderCode(Plane Plane) {
    List<Transponder> listTransponder = new ArrayList<>(Plane.getListTransponder());
    Transponder newest = listTransponder.stream().max(Comparator.comparing(Transponder::getDateInserted)).get();
    return newest.getCode();
}

// OTHER METHODS TO GET MOST RECENT RECORD

问题 有没有更好的方法来计算 child 的最近记录,更有效地使用模型映射器(自定义方法?)

如果 MapStruct 更好地支持获取最新的 child ,我愿意更改为 MapStruct。

最佳答案

我过去曾简单地使用过 ModelMapper。我建议使用 mapstruct,因为我个人觉得它更容易使用。我知道您的映射可以在那里完成;)。在 Mapstruct 中,您的 Mapper 可能看起来像这样:

@MapperConfig(
        componentModel = "spring",
        builder = @Builder(disableBuilder = true)
)
public interface PlaneMapper {

    @Mapping(target = "lastMaintCheck", ignore = true)
    PlaneDTO planeToPlaneDTO(Plane plane);

    @AfterMapping
    default void customCodePlaneMapping(Plane source, @MappingTarget PlaneDTO target) {
        target.setLastMaintCheck(source.getListMaintCheck.stream().max(Comparator.comparing(Transponder::getDateInserted)).get())
   }

您的映射器调用将只有一行:

@Service
@RequiuredArgsConstructor
public class someService{

    private final PlaneMapper planeMapper;

    public void someMethod(){
        ....
        PlaneDTO yourMappedPlaneDTO = planeMapper.planeToPlaneDTO(plane);
        ....
    }

我没有填写所有值。但我希望这个概念很清楚。

编辑:

您还必须添加“mapstruct-processor”的依赖项,以便可以生成 MapperImpl 类。

    <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>${org.mapstruct.version}</version>
        <scope>provided</scope>
        <optional>true</optional>
    </dependency>

关于java - 模型映射器 - 使用自定义方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/71823910/

相关文章:

java - 到达列表末尾时的链表

java - 如何使用Android的ParcelFileDescriptor和Documents Provider返回字节数据

java - Tomcat + OpenSSL 符号查找报错 undefined symbol EC_KEY_new_by_curve_name

java - 日期与时间戳与日历?

java - Spring数据事务控制

java - ActiveMQ 不活跃代理

MapStruct:将一个实体与该实体相同类型的字段进行映射

Spring Redis连接失败套接字超时: read timed out

java - Mapstruct 从字符串到具有相同类型的多个字段的嵌套对象

java - 使用 Mapstruct 将 Collection 映射到 Map,反之亦然