请注意:如果这确实是实现我所寻找的目标的唯一方法,那么我会接受基于XML的解决方案,但我更喜欢使用Dozer的Java API的解决方案。
我是推土机的新手,正在尝试了解如何使用其API。它似乎默认为字段级映射(如果字段名称匹配),并允许在字段级映射(基于字段名称)不可能或不符合应用程序需要的情况下使用自定义映射器和转换器。
我有一种情况,我的应用程序将接受一个DTO,例如,ReportedIssue(一个由用户报告并通过HTTP发送到我的应用程序的问题)和一个
issue(一个将持久化到MySQL DB的数据实体)。
以下是我的两个对象:
@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;
}
因此,在应用程序前端,用户可以报告问题。前端将一个JSON版本的ReportedIssue发送到后端,在那里JSON被反序列化为一个DTO bean。然后,我需要Dozer将我的ReportedIssue转换为一个实体,然后我可以轻松地将其保存到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似乎主要用于双向映射用例。然而,在我的应用程序中,我永远不会有问题实例,需要将其映射回报告问题实例。因此,我只需要来自ReportedIssue的单向映射--
Gauntham的答案会奏效的。另一种选择:
实现com.github.推土机绘图机。果心BeanFactory您的自定义BeanFactory可以处理
Issue issue = new Issue();
issue.setRefId(UUID.randomUUID().toString());
issue.setReportedOn(DateTimeUtils.nowInUTC());
issue.setReporter(authService.currentUser());
然后根据您的喜好,这也可以进入豆子工厂
issue.setType(IssueUtils.determineType(source));
或者您可以在映射中单独处理它。需要知道如何调用IssueUtils,因此这要么是1)客户转换器,要么是2)对DTO或实体的更改,以便通过getter或setter获得功能。
最后,这一行将在Dozer Java API映射中处理
issue.setInfo(destination.getInfo());
就个人而言,我喜欢推土机的com.github.推土机绘图机。果心装载机。应用程序编程接口。BeanMappingBuilder,其中可以明确告诉它如何映射2个bean,指定要使用的bean工厂和特定字段的自定义转换器。
mapping(ReportedIssue.class, Issue.class, oneWay(), wildcard(true), beanFactory(IssueBeanFactory.class.getName()).fields("this", "type", customConverter(IssueTypeConverter.class)
oneWay()、通配符(布尔)和beanFactory(字符串)可在推土机的TypeMappingOptions中找到,customConverter(Class.Class)可在推土机的FieldMappingOptions中找到。
实际上,它可以在没有自定义转换器的情况下完成,在您的dto类中使用自定义getter方法来对应问题
中的字段。Dozer通过尝试调用源类中相应名称的getter方法来映射目标类中的每个字段。
public class ReportedIssue {
// fields.......
public String getRefId() {
UUID.randomUUID().toString()
}
public IssueType getType() {
IssueUtils.determineType(this);
}
// similarly create getters for other required fields.
}
但对于问题中的报告者字段,您需要一个AuthService对象。我建议编写一个静态方法,如下所示:
public static Issue getIssue(AuthService auth, ReportedIssue dto) {
Issue issue = //map using dozer
issue.setReporter(authService.currentUser());
return issue;
}
我一直在寻找在推土机映射中设置常量值的解决方案,并且在stackoverflow上阅读了很多关于这个问题的答案。所以我决定使用推土机自定义转换器。 让我澄清一下我的情况。 我有两个具有以下字段的bean: 豆A: Bean B: 的字段应始终等于。 因此,我创建了一个自定义转换器: 以及以下映射: 它工作得很好,并将值设置为。但是这种方法看起来很糟糕: 我必须在XML映射中设置一个字段作为源,才能
我不确定我是否正确理解推土机映射器中的自定义创建方法。我需要将int类型的bean属性转换为TransTypeCodebook对象实例。但我得到了: 我的TransTypeCodebook课程 映射器部分 我设法通过自定义转换器解决了这个问题,但我不确定我是否理解自定义创建方法的概念,我想知道这个字符串是从哪里来的。有人能解释一下吗?
考虑以下类。如何在不使用自定义转换器的情况下使用Dozer将A类转换为B类? 有人能为上述类提供推土机映射XML吗?
在Dozer的帮助下,我想将映射到DTO类 但是这两种设置
我想让推土机地图成为我的职业: 到生成的,如下所示: . 也就是说,我正在尝试将嵌套类的字段映射到平面键目标。我使用的是JavaAPI的Dozer,而不是xml。我无法找到适当的构建器配置来管理它。基本代码类似于:
我试图使用Dozer映射UUID字段,遇到了Dozer github上提到的一个问题: https://github.com/DozerMapper/dozer/issues/83 问题是-显然,Dozer依赖于UUID中不存在的默认无参数构造函数。因此,该链接显示了如何告知推土机执行参考复制。然而,使用该提示并没有帮助,我仍然会遇到以下异常: org.dozer.java.lang.java.u