返回
MapStruct对象映射常见问题和最佳实践
java
2024-03-17 11:29:29
使用 MapStruct 进行不同数据源的对象映射
在软件开发中,我们需要在不同的数据对象之间进行转换。MapStruct 是一个代码生成库,可以自动生成对象之间的映射实现。
问题
我们有一个场景,需要将 Source
对象映射到 Target
对象。Source
对象有一个字符串字段 str3
,而 Target
对象有两个字符串字段 (str1
和 str2
) 和一个嵌套对象 anotherObj
。anotherObj
对象也有两个字符串字段 (str3
和 str4
)。
最初的 MapStruct 映射如下:
@Mapping(target = "anotherObj", source = "request", qualifiedByName = "mapAnotherObjToSource")
@Mapping(target = "anotherObj.str4", source = "str4")
Target convert(Source request, String str4);
然而,执行映射时,我们遇到了一个错误:
Java: No read accessor found for property anotherObj in target type.
错误分析
错误表明 MapStruct 找不到目标类型 Target
中 anotherObj
属性的读取访问器。这是因为我们没有为 anotherObj
属性定义 getter 方法。
解决方案
1. 添加 getter 方法
@Getter
public class Target {
public String str1;
public String str2;
public AnotherObj anotherObj;
}
2. 使用 @AfterMapping
方法
除了添加 getter 方法,我们还可以使用 @AfterMapping
方法来处理映射后的自定义逻辑。@AfterMapping
方法将在映射过程完成后调用。
@AfterMapping
default void handleStr4(@MappingTarget Target target, Source source, String str4) {
if (target.getAnotherObj() != null) {
target.getAnotherObj().setStr4(str4);
}
}
结论
在使用 MapStruct 进行对象映射时,重要的是确保为所有目标属性定义 getter 方法。此外,@AfterMapping
方法可以让你在映射过程后执行自定义逻辑。遵循这些准则,我们可以创建健壮且可维护的对象映射实现。
常见问题解答
1. 什么时候使用 MapStruct?
- 当需要在不同的数据对象之间进行转换时。
- 当需要创建可维护且可扩展的映射实现时。
2. 如何添加 getter 方法?
- 使用注解
@Getter
(Java 9+)或手动定义 getter 方法。
3. 什么时候使用 @AfterMapping
方法?
- 当需要在映射过程后执行自定义逻辑时。
- 当需要设置默认值或进行其他计算时。
4. 如何避免目标类型中属性没有读取访问器的错误?
- 确保为所有目标属性定义 getter 方法。
5. 如何使用 @Mapping
注解进行更细粒度的控制?
- 使用
@Mapping
注解的属性参数和方法参数可以配置映射的细节。 - 可以指定转换器、源属性、目标属性、忽略字段和更多选项。