是否可以从列表的特定元素映射到自身?

Is it possible to map from a specific element of a list to self?

给出以下 类:

public class Person {
    private String name;
    private List<Role> roles;

    public String getRoleByType(String type){
        for(Role role : roles){
            if(type.equals(role.getType())){
                return role;
            }
        }

        return null;
    }
}

public interface Role {
    public String getType();
}

public class Driver extends Role {
    private String driverLicenseNr;

    public String getType(){
        return "Driver";
    }
}

public class Professional extends Role {
    private String occupation;

    public String getType(){
        return "Professional";
    }
}

public class DriverDTO {
    private String name;
    private String driverLicenseNr;
}

我想要完成的是将 Person 映射到 DriverDTO。

我正在尝试这样的事情:

@Mapper
public abstract class DriverMapper {
    
    @Mapping(target = ".", expression = "java(driver.getRoleByType(\"Driver\"))")
    public abstract DriverDTO convert(Person person);

    public abstract void driverToDriverDTO(Driver driver, @MappingTarget DriverDTO driverDto);
}

但是注释处理器不能简单地用它来生成代码。抛出 nullPointerException。 如果我这样做(为了简化隐藏了一些编程细节):

@Mapper
public abstract class DriverMapper {
    
    @Mapping(target = "driverLicenseNr", expression = "java(driver.getRoleByType(\"Driver\").getDriverLicenseNr())")
    public abstract DriverDTO convert(Person person);
}

它有效,但我想利用自动映射,在这种情况下我不会。 target="." 似乎只适用于使用源中单个对象的简单映射。这是真的还是我选择了错误的路径来解决这个问题?

当使用表达式时,MapStruct 不进行任何计算并使用生成代码中的内容。

我建议您执行以下操作:

@Mapper
public abstract class DriverMapper {
    
    public DriverDTO convert(Person person) {
        if (person == null) {
            return null;
        }

        Role role = person.getRoleByType("Driver");

        Driver driver = role instanceof Driver ? (Driver) role : null;

        return convert(person, driver);
    }

    @Mapping(target = ".", source = "driver")
    protected abstract DriverDTO convert(Person person, Driver driver);

}