返回

MapStruct 嵌套对象映射难题:如何巧妙应对?

java

嵌套对象映射:巧用 MapStruct 处理多个来源

嵌套对象映射的挑战

在使用 MapStruct 进行对象映射时,你会遇到处理嵌套对象的挑战。嵌套对象是指对象内部包含其他对象。当需要将这些嵌套对象从多个来源映射到目标 DTO 时,可能会出现问题。

解决嵌套对象映射问题

MapStruct 提供了一种机制来解决此问题,即 @Mapping 注解。使用 @Mapping 注解,你可以指定用于映射嵌套对象的特定方法。

示例:嵌套对象映射

考虑以下代码示例:

public class X {
    private Y y;
    private Integer xa;
    private Integer xb;
}

public class Y {
    private Integer ya;
    private Integer yb;
}

public class Z {
    private Integer za;
    private Integer zb;
}

以及它们的 DTO:

public class XDTO {
    private YDTO y;
    private Integer xa;
    private Integer xb;
}

public class YDTO {
    private ZDTO z;
    private Integer ya;
    private Integer yb;
}

public class ZDTO {
    private Integer za;
    private Integer zb;
}

我们的目标是创建以下映射器:

@Mapper
public interface XYZMapper {

    XDTO xToXDTO(X x, Z z);
    YDTO yToYDTO(Y y, Z z);
    ZDTO zToZDTO(Z z);
}

这样,当我们调用 xToXDTO 方法时,它将自动调用 yToYDTO 方法来映射 YYDTO

使用 @Mapping 注解

为了实现嵌套对象映射,我们需要使用 @Mapping 注解:

@Mapper
public interface XYZMapper {

    @Mapping(source = "y", target = "y", qualifiedByName = "yToYDTO")
    XDTO xToXDTO(X x, Z z);
    
    YDTO yToYDTO(Y y, Z z);
    ZDTO zToZDTO(Z z);
}

通过添加 qualifiedByName = "yToYDTO",我们指定了在映射 y 属性时应使用名为 yToYDTO 的方法。

生成的代码

MapStruct 将生成以下代码:

public XDTO xToXDTO(X x, Z z) {
    if ( x == null && z == null ) {
        return null;
    }

    XDTO xDTO = new XDTO();

    if ( x != null ) {
        xDTO.setY( yToYDTO( x.getY(), z ) );
        xDTO.setXa( x.getXa() );
        xDTO.setXb( x.getXb() );
    }

    return xDTO;
}

你可以看到它现在正在调用正确的 yToYDTO 方法来映射 YYDTO

结论

使用 @Mapping 注解,我们可以轻松地处理嵌套对象映射。这使我们能够将嵌套对象从多个来源映射到目标 DTO,从而简化了复杂的对象映射任务。

常见问题解答

  1. @Mapping 注解有什么其他用途?

    • @Mapping 注解还可用于指定其他映射选项,例如忽略属性、自定义转换和映射多态类型。
  2. 除了 @Mapping 注解之外,MapStruct 还提供了哪些其他嵌套对象映射选项?

    • MapStruct 还提供了 @Mapper 注解,它允许你将多个接口组合到一个映射器中,这对于管理嵌套对象映射非常有用。
  3. 嵌套对象映射在哪些场景中很有用?

    • 嵌套对象映射在需要将来自不同来源的复杂对象映射到 DTO 或实体时非常有用。
  4. 是否可以使用 MapStruct 来映射任意数量的嵌套对象?

    • 是的,MapStruct 可以处理任意数量的嵌套对象,使你可以灵活地映射复杂的对象结构。
  5. MapStruct 是否支持双向映射?

    • 是的,MapStruct 支持双向映射,使你可以将对象从 DTO 映射回原始类型。