MapStruct:将 2 个对象映射到第 3 个对象

Posted

技术标签:

【中文标题】MapStruct:将 2 个对象映射到第 3 个对象【英文标题】:MapStruct: Mapping 2 objects to a 3rd one 【发布时间】:2016-03-11 21:07:43 【问题描述】:

我有 Object1 和 Object2。现在,我想用 1 和 2 的属性映射 object3。

说,我有 2 个对象:

1. User: first_name, last_name, id
2. Address: street, locality, city, state, pin, id

现在,有了这些,我想把它映射到

User_View: firstName, lastName, city, state.

其中,名字和姓氏将来自用户对象 以及来自 Address 对象的城市和州。

现在,我的问题是,该怎么做?

但是,目前,我正在这样做

@Mapper    
public abstract class UserViewMapper 
        @Mappings(
                    @Mapping(source = "first_name", target = "firstName"),
                    @Mapping(source = "last_name", target = "lastName"),
                    @Mapping(target = "city", ignore = true),
                    @Mapping(target = "state", ignore = true)

            )
            public abstract UserView userToView(User user);

        public UserView addressToView(UserView userView, Address address) 

                if (userView == null) 
                    return null;
                

                if (address == null) 
                    return null;
                

                userView.setCity(address.getCity());
                userView.setState(address.getState()); 

            return userView;

            
    

但是,在这里,我必须在addressToView()中手动编写映射。

因此,有什么方法可以避免这种情况吗?

或者,处理这种情况的首选方法是什么?

【问题讨论】:

【参考方案1】:

使用 MapStruct 你错过了使用 @Mapper 注释的步骤。 @Mapper 将创建映射的实现。

您应该查看此链接上的文档http://mapstruct.org/documentation/stable/reference/html/

具体

    定义映射器

在本节中,您将学习如何定义一个 bean 映射器 MapStruct 以及您必须这样做的选项。 3.1 基本映射

要创建一个映射器,只需定义一个带有所需的 Java 接口 映射方法并使用 org.mapstruct.Mapper 对其进行注释 注释:

@Mapper
public interface CarMapper 

    @Mappings(
        @Mapping(source = "make", target = "manufacturer"),
        @Mapping(source = "numberOfSeats", target = "seatCount")
    )
    CarDto carToCarDto(Car car);

    @Mapping(source = "name", target = "fullName")
    PersonDto personToPersonDto(Person person);

@Mapper 注释导致 MapStruct 代码生成器创建 在构建时实现 CarMapper 接口。

【讨论】:

【参考方案2】:

您可以使用多个源参数声明一个映射方法,并在您的@Mapping 注释中引用所有这些参数的属性:

@Mapper
public abstract class UserViewMapper 

    @Mapping(source = "first_name", target = "user.firstName"),
    @Mapping(source = "last_name", target = "user.lastName"),
    public abstract UserView userAndAddressToView(User user, Address address);

由于“城市”和“州”属性名称在源和目标中匹配,因此无需映射它们。

有关详细信息,另请参阅参考文档中的 "Defining a mapper" 章节。

【讨论】:

感谢您的快速回复。一个问题,什么,如果我在两个输入对象中具有相同的属性,这意味着,如果用户和地址都具有相同名称的属性,将映射哪个属性,或者我将如何定义该属性的源? 我认为您在回答中混淆了源和目标。应该是:@Mapping(source = "user.first_name", target = "firstName")

以上是关于MapStruct:将 2 个对象映射到第 3 个对象的主要内容,如果未能解决你的问题,请参考以下文章

MapStruct 使用指南

MapStruct使用说明

学习笔记 - MapStruct 映射工具

学习笔记 - MapStruct 映射工具

MapStruct 一文读懂

实体映射最强工具类:MapStruct 真香!