[英]One way mapping in Dozer using custom converter
请注意:虽然我会接受基于 XML 的解决方案,如果这确实是完成我正在寻找的唯一方法,但我更喜欢使用 Dozer 的 Java API 的解决方案。
我是Dozer的新手,正在尝试弄清楚如何使用它的 API。 它似乎默认为字段级映射(如果字段名称匹配)并允许自定义映射器和转换器,以防字段级映射(基于字段名称)对于您的应用程序需求是不可能或不合逻辑的。
我的应用程序将采用 DTO,例如ReportedIssue
(用户报告并通过 HTTP 发送到我的应用程序的问题)和Issue
实体(将持久保存到 MySQL 数据库的数据实体)。
这是我的两个对象:
@Data
public class ReportedIssue {
private String typeRefId;
private String reporterRefId;
private String info;
}
@Entity
@Table(name = "issues")
@Data
public class Issue {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "issue_ref_id")
private String refId;
@Column(name = "issue_tracking_number")
private String trackingNumber;
@OneToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "issue_type_id", referencedColumnName = "issue_type_id")
private IssueType type;
@Column(name = "issue_reported_on")
private Date reportedOn;
@OneToOne(fetch = FetchType.EAGER, cascade = {CascadeType.PERSIST, CascadeType.MERGE})
@JoinColumn(name = "issue_reporter_id", referencedColumnName = "account_id")
private Account reporter;
@Column(name = "issue_info")
private String info;
}
因此,在应用程序前端,用户可以报告问题。 前端将ReportedIssue
的 JSON 版本发送到后端,其中 JSON 被反序列化为ReportedIssue
DTO bean。 然后我需要 Dozer 将我的ReportedIssue
转换为Issue
实体,然后我可以轻松地将其保存到我的 MySQL 数据库中。
这是我最好的尝试:
public class ReportedIssueConverter extends DozerConverter<ReportedIssue, Issue> {
private AuthService authService;
public ReportedIssueConverter(AuthService authService, Class<ReportedIssue> prototypeA, Class<Issue> prototypeB) {
super(prototypeA, prototypeB);
this.authService = authService;
}
public ReportedIssueConverter(Class<ReportedIssue> prototypeA, Class<Issue> prototypeB) {
super(prototypeA, prototypeB);
}
@Override
public Issue convertTo(ReportedIssue source, Issue destination) {
Issue issue = new Issue();
issue.setRefId(UUID.randomUUID().toString());
issue.setType(IssueUtils.determineType(source));
issue.setReportedOn(DateTimeUtils.nowInUTC());
issue.setReporter(authService.currentUser());
issue.setInfo(destination.getInfo());
return issue;
}
@Override
public ReportedIssue convertFrom(Issue source, ReportedIssue destination) {
throw new UnsupportedOperationException("we currently don't map from issues to reported issues");
}
}
这里有几个问题。 一方面,这样的定制转换器是否必要? 或者是否有“更好”(符合更多标准或使用普遍接受的推土机实践)的方式来使用推土机 API 执行此转换? 但主要是,这个DozerConverter
似乎适用于双向映射用例。 然而,在我的应用程序中,我永远不会有Issue
实例,需要将其 map 回传给ReportedIssue
DTO 实例。 所以我只需要来自ReportedIssue --> Issue
的单向映射。 我是通过抛出UnsupportedOperationException
正确使用推土机,还是有另一个接口或 API 技巧可以用来仅利用我需要的单向映射?
它实际上可以在没有自定义转换器的情况下使用您的 dto class 中对应于Issue
中的字段的自定义 getter 方法来完成。 Dozer 的工作原理是通过尝试调用源 class 中相应名称的 getter 方法来映射目标 class 中的每个字段。
public class ReportedIssue {
// fields.......
public String getRefId() {
UUID.randomUUID().toString()
}
public IssueType getType() {
IssueUtils.determineType(this);
}
// similarly create getters for other required fields.
}
但是对于Issue
中的reporter
字段,您需要一个AuthService
object。 我建议编写如下 static 方法:
public static Issue getIssue(AuthService auth, ReportedIssue dto) {
Issue issue = //map using dozer
issue.setReporter(authService.currentUser());
return issue;
}
冈瑟姆的回答会奏效。 另外的选择:
实现一个 com.github.dozermapper.core.BeanFactory 你的自定义 BeanFactory 可以处理
Issue issue = new Issue();
issue.setRefId(UUID.randomUUID().toString());
issue.setReportedOn(DateTimeUtils.nowInUTC());
issue.setReporter(authService.currentUser());
然后根据你的喜好,这个也可以 go 进豆厂
issue.setType(IssueUtils.determineType(source));
或者您可以在映射中单独处理。 有些东西需要知道如何调用 IssueUtils,因此要么是 1) 客户转换器,要么是 2) 更改 DTO 或实体以通过 getter 或 setter 获得功能。
最后,这条线将在 Dozer Java API 映射中处理
issue.setInfo(destination.getInfo());
Personally, I like Dozer's com.github.dozermapper.core.loader.api.BeanMappingBuilder where you can explicitly tell it how to map 2 beans, specify the bean factory to use and the custom converter for a specific field.
mapping(ReportedIssue.class, Issue.class, oneWay(), wildcard(true), beanFactory(IssueBeanFactory.class.getName()).fields("this", "type", customConverter(IssueTypeConverter.class)
oneWay()、wildcard(boolean) 和 beanFactory(String) 在 Dozer 的 TypeMappingOptions 中找到,customConverter(Class.class) 在 Dozer 的 FieldMappingOptions 中找到。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.