当前位置: 首页 > 知识库问答 >
问题:

MapStruct:丰富映射注释以定义自定义映射器

闽哲
2023-03-14

以下是我的上下文:我使用byteBuddy动态生成一个类,该类根据外部配置将一个对象转换为另一个对象。我遇到了一些问题,我想找到一个替代方案,这就是我发现MapStruct的方式。

因此,我试图构建简单的映射器,我想知道是否有可能自定义注释以添加转换函数。例如,我想要:

@Mapping(
    source = "mySourceField", 
    sourceType = "String",
    target = "myTargetField",
    targetType = "Integer",
    transformation = {"toInteger", "toSquare"}
),

在mapper实现中,我会有如下内容:

 public TypeDest toSiteCatTag(TypeSrc obj) {

    if ( obj == null ) {

        return null;
    }

    TypeDest objDest = new TypeDest();

    objDest.myTargetField = Formatter.toSquare(
        Formatter.toInteger(obj.mySourceField));

    return objDest;
}

如果有人能帮我做到这一点,我将不胜感激,这将节省我很多时间。

提前谢谢。

共有1个答案

姚子石
2023-03-14

如果您的两个类型TypeDestTypeSrc不是在运行时生成的,即它们是您编译的类,那么您可以实现您想要的。MapStruct不能在运行时工作,因为它是一个注释处理器,可以生成java代码。如果存在一些问题,比如试图映射不存在的字段,或者存在不明确的映射方法,那么就会出现编译时错误。

它看起来像:

@Mapper
public interface MyMapper {

    @Mapping(source = "mySourceField", target = "myTargetField", qualifiedByName = "myTransformation")// or you can use a custom @Qualifier annotation with qualifiedBy
    TypeDest toSiteCatTag(TypeSrc obj);

    @Named("myTransformation")// or your custom @Qualifier annotation
    default Integer myCustomTransformation(String obj) {
        return Formatter.toSquare(Formatter.toInteger(obj));
    }
}

有一种方法可以在映射器中不使用自定义方法的情况下完成它,但您需要在某个地方有一个方法来应用toIntger然后toSquare转换。如果您有一个方法,其签名为整数平方字符串(String obj)在您的格式中。

例如

@Qualifier
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.CLASS)
public @interface SquaredString {}

public class Formatter {

    @SquaredString// you can also use @Named, this is just as an example
    public static Integer squaredString(String obj) {
        return toSquare(toInteger(obj));
    }
    //your other methods are here as well
}

然后,您可以在地图绘制程序中执行此操作:

@Mapper(uses = { Formatter.class })
public interface MyMapper {

    @Mapping(source = "mySourceField", target = "myTargetField", qualifiedBy = SquaredString.class)
    TypeDest toSiteCatTag(TypeSrc obj);
}

上面的示例将仅应用于特定的映射,因为使用了合格的ByName/合格的。如果您想以不同的方式将String转换为整数,那么您可以在您的Mapper或Mapper#中的某些类中定义一个方法,并带有签名整数转换字符串(String obj)。然后,Mapstrt将把从String整数的转换委托给此方法。

您可以在参考留档中找到有关使用限定符进行映射的更多信息,并在此处找到有关映射方法解析的更多信息。

 类似资料:
  • 例如,我有以下接口映射器: 在代码中,您可以看到映射和一些默认方法,其中包含其他映射。如何在Mapstruct映射中使用这些方法,以便Mapstruct使用这些方法在字段中填充值?

  • 我有一个映射定义为 其中定义如下: 反向映射是使用处理的。如何为反向映射指定自定义映射?

  • 我有两个对象,除了date成员外,其他成员都相同。在obj1中,date是java.sql.date,obj2.date是long(纪元)。 我需要编写一个映射器来将obj1映射到obj2。这就是我试图做的: 但是mapperImpl只有自己的日期转换实现: 我得到了: 这种转换的正确方式是什么?

  • 我有一个用例,其中我需要维护两组JSON输出,一组具有JSON属性的漂亮名称,另一组没有。所以我决定自定义ObjectMapper,以便它忽略字段上的@JSONProperty(“pretty name”)注释,而使用字段属性名。在本例中,希望得到以下JSON输出 具有漂亮名称的JSON输出如下所示 我的ObjectMapper配置代码如下所示 我看了一些其他的答案,但对我不起作用。我得到了一个N

  • 我有一个要求,在那里我将从2列像天和月的数据,但我想把它转换成一个日期对象,并把它设置成我的bean类。 这是否可能不添加属性到java类? 我尝试检查自定义结果处理程序,但示例不够清晰。在从select方法返回之前,是否有钩子来运行某种自定义处理程序?

  • 这是我的例子。 我希望toDto方法使用toDto将Employee映射到EmployeeDto,但mapstruct会生成employeeDtoToEmployeeDto方法。我该怎么修? 谢谢