您现在的位置是:首页 > 博文答疑 > MapStruct 博文答疑

MapStruct

Leo2025-03-31【5】

简介

基本类型与包装类型的映射

基本类型和其对应的包装类型之间的映射,MapStruct 能够自动处理。
import org.mapstruct.Mapper;
import org.mapstruct.factory.Mappers;

// 源对象
class Source {
    private Integer age;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }
}

// 目标对象
class Target {
    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

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

    Target sourceToTarget(Source source);
}

public class Main {
    public static void main(String[] args) {
        Source source = new Source();
        source.setAge(25);
        Target target = SourceTargetMapper.INSTANCE.sourceToTarget(source);
        System.out.println("Age in target: " + target.getAge());
    }
}
 
在上述代码中,Source 类里 age 是 Integer 类型,而 Target 类中 age 为 int 类型。MapStruct 会自动完成这种基本类型与包装类型间的转换。

自定义类型转换

要是源类型和目标类型无法自动转换,就需要自定义转换方法。
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

// 源对象
class Source {
    private String dateString;

    public String getDateString() {
        return dateString;
    }

    public void setDateString(String dateString) {
        this.dateString = dateString;
    }
}

// 目标对象
import java.util.Date;

class Target {
    private Date date;

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}

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

    @Mapping(source = "dateString", target = "date", qualifiedByName = "stringToDate")
    Target sourceToTarget(Source source);

    default Date stringToDate(String dateString) {
        // 简单示例,实际中可能需要更复杂的日期解析
        try {
            java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");
            return sdf.parse(dateString);
        } catch (java.text.ParseException e) {
            return null;
        }
    }
}

public class Main {
    public static void main(String[] args) {
        Source source = new Source();
        source.setDateString("2024-01-01");
        Target target = SourceTargetMapper.INSTANCE.sourceToTarget(source);
        System.out.println("Date in target: " + target.getDate());
    }
}
 
在这个例子中,Source 类的 dateString 是 String 类型,Target 类的 date 是 Date 类型。借助 @Mapping 注解的 qualifiedByName 属性,指定使用自定义的 stringToDate 方法来完成转换。

使用 uses 属性引用其他映射器

当类型转换较为复杂,可使用 uses 属性引用其他映射器。
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;

// 源对象
class Source {
    private InnerSource innerSource;

    public InnerSource getInnerSource() {
        return innerSource;
    }

    public void setInnerSource(InnerSource innerSource) {
        this.innerSource = innerSource;
    }
}

class InnerSource {
    private String name;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}

// 目标对象
class Target {
    private InnerTarget innerTarget;

    public InnerTarget getInnerTarget() {
        return innerTarget;
    }

    public void setInnerTarget(InnerTarget innerTarget) {
        this.innerTarget = innerTarget;
    }
}

class InnerTarget {
    private String fullName;

    public String getFullName() {
        return fullName;
    }

    public void setFullName(String fullName) {
        this.fullName = fullName;
    }
}

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

    @Mapping(source = "name", target = "fullName")
    InnerTarget innerSourceToInnerTarget(InnerSource innerSource);
}

@Mapper(uses = InnerMapper.class)
public interface SourceTargetMapper {
    SourceTargetMapper INSTANCE = Mappers.getMapper(SourceTargetMapper.class);

    @Mapping(source = "innerSource", target = "innerTarget")
    Target sourceToTarget(Source source);
}

public class Main {
    public static void main(String[] args) {
        InnerSource innerSource = new InnerSource();
        innerSource.setName("John");
        Source source = new Source();
        source.setInnerSource(innerSource);
        Target target = SourceTargetMapper.INSTANCE.sourceToTarget(source);
        System.out.println("Full name in target: " + target.getInnerTarget().getFullName());
    }
}
在这个示例里,Source 类包含 InnerSource 类型的属性,Target 类包含 InnerTarget 类型的属性。通过 @Mapper 注解的 uses 属性引用 InnerMapper 来处理 InnerSource 到 InnerTarget 的转换。