【发布时间】:2021-06-15 16:57:47
【问题描述】:
请注意:虽然我会接受基于 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 实例,需要将其映射回ReportedIssue DTO 实例。所以我只需要来自ReportedIssue --> Issue 的单向映射。我是通过抛出 UnsupportedOperationException 正确使用 Dozer,还是有其他接口或 API 技巧可以用来仅利用我需要的单向映射?
【问题讨论】: