mapstruct使用指南(2)

多个源类

有时,单个类不足以构建DTO,我们可能希望将多个类中的值聚合为一个DTO,供终端用户使用。这也可以通过在@Mapping注解中设置适当的标志来完成。

我们先新建另一个对象 Education:

public class Education {
    private String degreeName;
    private String institute;
    private Integer yearOfPassing;
    // getters and setters or builder
}

然后向 DoctorDto中添加一个新的字段:

public class DoctorDto {
    private int id;
    private String name;
    private String degree;
    private String specialization;
    // getters and setters or builder
}

接下来,将 DoctorMapper 接口更新为如下代码:

@Mapper
public interface DoctorMapper {
    DoctorMapper INSTANCE = Mappers.getMapper(DoctorMapper.class);

    @Mapping(source = "doctor.specialty", target = "specialization")
    @Mapping(source = "education.degreeName", target = "degree")
    DoctorDto toDto(Doctor doctor, Education education);
}

我们添加了另一个@Mapping注解,并将其source设置为Education类的degreeName,将target设置为DoctorDto类的degree字段。

如果 Education 类和 Doctor 类包含同名的字段,我们必须让映射器知道使用哪一个,否则它会抛出一个异常。举例来说,如果两个模型都包含一个id字段,我们就要选择将哪个类中的id映射到DTO属性中。

子对象映射

多数情况下,POJO中不会包含基本数据类型,其中往往会包含其它类。比如说,一个Doctor类中会有多个患者类:

public class Patient {
    private int id;
    private String name;
    // getters and setters or builder
}

在Doctor中添加一个患者列表List

public class Doctor {
    private int id;
    private String name;
    private String specialty;
    private List<Patient> patientList;
    // getters and setters or builder
}

因为Patient需要转换,为其创建一个对应的DTO:

public class PatientDto {
    private int id;
    private String name;
    // getters and setters or builder
}

最后,在 DoctorDto 中新增一个存储 PatientDto的列表:

public class DoctorDto {
    private int id;
    private String name;
    private String degree;
    private String specialization;
    private List<PatientDto> patientDtoList;
    // getters and setters or builder
}

在修改 DoctorMapper之前,我们先创建一个支持 Patient 和 PatientDto 转换的映射器接口:

@Mapper
public interface PatientMapper {
    PatientMapper INSTANCE = Mappers.getMapper(PatientMapper.class);
    PatientDto toDto(Patient patient);
}

这是一个基本映射器,只会处理几个基本数据类型。

然后,我们再来修改 DoctorMapper 处理一下患者列表:

@Mapper(uses = {PatientMapper.class})
public interface DoctorMapper {

    DoctorMapper INSTANCE = Mappers.getMapper(DoctorMapper.class);

    @Mapping(source = "doctor.patientList", target = "patientDtoList")
    @Mapping(source = "doctor.specialty", target = "specialization")
    DoctorDto toDto(Doctor doctor);
}

因为我们要处理另一个需要映射的类,所以这里设置了@Mapper注解的uses标志,这样现在的 @Mapper 就可以使用另一个 @Mapper映射器。我们这里只加了一个,但你想在这里添加多少class/mapper都可以。

我们已经添加了uses标志,所以在为DoctorMapper接口生成映射器实现时,MapStruct 也会把 Patient 模型转换成 PatientDto ——因为我们已经为这个任务注册了 PatientMapper

显然,除了toDto()映射方法外,最终实现中还添加了一个新的映射方法——patientListToPatientDtoList()。这个方法是在没有显式定义的情况下添加的,只是因为我们把PatientMapper添加到了DoctorMapper中。

该方法会遍历一个Patient列表,将每个元素转换为PatientDto,并将转换后的对象添加到DoctorDto对象内中的列表中。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值