我想使用 ModelMapper 将实体转换为 DTO 并返回。大多数情况下它有效,但我如何自定义它。它有太多的选择,以至于很难弄清楚从哪里开始。什么是最佳实践?
我会在下面自己回答,但如果另一个答案更好,我会接受。
原文由 John Henckel 发布,翻译遵循 CC BY-SA 4.0 许可协议
我想使用 ModelMapper 将实体转换为 DTO 并返回。大多数情况下它有效,但我如何自定义它。它有太多的选择,以至于很难弄清楚从哪里开始。什么是最佳实践?
我会在下面自己回答,但如果另一个答案更好,我会接受。
原文由 John Henckel 发布,翻译遵循 CC BY-SA 4.0 许可协议
我在使用 ModelMapper 进行映射时遇到了问题。不仅属性而且我的源和目标类型都不同。我通过这样做解决了这个问题 - >
如果源和目标类型不同。例如,
@Entity
class Student {
private Long id;
@OneToOne
@JoinColumn(name = "laptop_id")
private Laptop laptop;
}
和 Dto ->
class StudentDto {
private Long id;
private LaptopDto laptopDto;
}
此处,源和目标类型不同。因此,如果您的 MatchingStrategies 是严格的,您将无法在这两种不同类型之间进行映射。现在要解决这个问题,只需将下面的代码放在您的控制器类或您要使用 ModelMapper-> 的任何类的构造函数中
private ModelMapper modelMapper;
public StudentController(ModelMapper modelMapper) {
this.modelMapper = modelMapper;
this.modelMapper.typeMap(Student.class, StudentDto.class).addMapping(Student::getLaptop, StudentDto::setLaptopDto);
}
而已。现在您可以轻松使用 ModelMapper.map(source, destination) 。它会自动映射
modelMapper.map(student, studentDto);
原文由 Muhammad Saimon 发布,翻译遵循 CC BY-SA 4.0 许可协议
2 回答11.6k 阅读✓ 已解决
8 回答6.6k 阅读
4 回答713 阅读✓ 已解决
2 回答3.4k 阅读
3 回答1.9k 阅读✓ 已解决
1 回答2.2k 阅读✓ 已解决
1 回答2.1k 阅读✓ 已解决
首先这里有一些链接
我对mm的印象是它的设计非常好。代码很扎实,读起来很愉快。但是,文档非常简洁,示例很少。该 api 也令人困惑,因为似乎有 10 种方法可以做任何事情,并且没有任何迹象表明您为什么要这样做。
有两种选择: Dozer 最受欢迎, Orika 因其 易用性而获得好评。
假设您仍然想使用 mm,这就是我所了解的。
主类
ModelMapper
应该是您应用中的单例。对我来说,这意味着使用 Spring 的 @Bean。对于简单的情况,它开箱即用。例如,假设您有两个类:使用适当的吸气剂/吸气剂。你可以这样做:
并且“名称”将从dd复制到di。
自定义 mm 的方法有很多种,但首先你需要了解它是如何工作的。
mm 对象包含每个有序类型对的 TypeMap,例如 和 将是两个 TypeMap。
每个 TypeMap 都 包含一个带有映射列表的 PropertyMap 。因此,在示例中,mm 将自动创建一个 TypeMap,其中包含具有单个映射的 PropertyMap。
我们可以这样写
它会输出
当您调用 mm.map() 时,这就是它的作用,
源/目标类型创建 TypeMap警告:这个流程图 有点记录, 但我不得不猜测很多,所以它可能不完全正确!
您可以自定义此过程的 _每个步骤_。但最常见的两种是
以下是 自定义 TypeMap 转换器 的示例:
注意 转换器是 _单向的_。如果要将 DogInfo 自定义为 DogData,则必须编写另一个。
这是 自定义 PropertyMap 的示例:
pm.configure 函数真的很时髦。这不是实际的代码。它是以某种方式被解释的虚拟 EDSL 代码。例如,setter 的参数是不相关的,它只是一个占位符。你可以在这里做很多事情,比如
请注意,自定义映射已 添加 到默认映射中,因此您 无需 指定
在您的自定义 PropertyMap.configure() 中。
在这个例子中,我必须编写一个 转换器 来将整数映射到布尔值。在大多数情况下,这不是必需的,因为 mm 会自动将 Integer 转换为 String 等。
我听说您还可以 使用 Java 8 lambda 表达式创建映射。我试过了,但我想不通。
最终建议和最佳实践
默认情况下,mm 使用
MatchingStrategies.STANDARD
这很危险。它很容易选择错误的映射并导致奇怪的、难以发现的错误。如果明年其他人向数据库添加一个新列怎么办?所以不要这样做。确保使用严格模式:始终编写单元测试并确保所有映射都经过验证。
使用
mm.addMappings()
修复任何验证失败,如上所示。将所有映射放在一个中心位置,在该位置创建 mm 单例。