我正在使用www.modelmapper.org并且我正在将相同的“平面”java DTO 映射到几个“分层”DTO。
“平面” DTO 具有许多原始属性。
“分层”有许多复杂类型,其中包含许多原始类型。这些 DTO 非常相似,但又不相同。
“扁平” DTO:
class TransactionRequest
{
String cashierNumber;
Long amount;
Integer currency;
public String getCashierNumber {..
...
}
“分层 DTO:
class PurchaseRequest
{
POSInfo posInfo;
Amount amount;
...
public PosInfo getPosInfo {..
public Amount getAmount { ..
...
}
class CancelRequest
{
POSInfo posInfo;
Amount amount;
...
public PosInfo getPosInfo {..
public Amount getAmount { ..
...
}
class Amount
{
BigDecimal value;
Integer currency;
public Integer getCurrency{..
...
}
class PosInfo
{
String cashierNumber;
public String getCashierNumber {..
}
TransactionRequest 应映射为 1) PurchaseRequest 和 2) CancelRequest。
问题之一是,金额必须从 Long(以次要单位)转换为 BigDecimal(以带十进制数字的主要单位)。我通过编写自己的 Long 到 BigDecimal 转换器来实现这一点。现在我遇到了以可重用方式定义所需映射的问题。我不想要的是为每个目标类型定义映射,如下所示:
class PurchaseMap extends PropertyMap<..
protected void configure()
{
using(new LongToBigDecimalConverter(...)).map().getAmount().setValue(source.getAmount());
...
}
class CancelMap extends PropertyMap<..
protected void configure()
{
using(new LongToBigDecimalConverter(...)).map().getAmount().setValue(source.getAmount());
...
}
我只想一次定义 Amount DTO 的映射(以及所有其他子类型映射,例如 PosInfo 等等),然后重新使用这些映射。我尝试了几个选项:
我尝试的第一件事是在我的 ModelMapper 中声明 TransactionRequest 到 Amount DTO 的映射。首先,我假设简单地声明这个映射就足以在将 TransactionRequest 映射到 PurchaseRequest 时使用映射机制。然而事实并非如此。
我尝试的第二件事确实有效,但似乎过于复杂:
- 我为 TransactionRequest 到 Amount 的映射创建了一个 PropertyMap。
- 我创建了一个自定义转换器 TransactionRequest 到 Amount。此转换器在其构造函数中需要一个 ModelMapper。我传递给构造函数的 ModelMapper 是从 1) 创建 PropertyMap 的 ModelMapper
- 我在 PurchaseRequest 和 CancelRequest 的 PropertyMaps 中使用这个转换器
这是代码:
public class AmountMap extends PropertyMap<TransactionRequest , Amount>
{
....
protected void configure()
{
using(new LongToBigDecimalConverter(...)).map().getAmount().setValue(source.getAmount());
}
...
}
}
public class TransactionRequestToAmountConverter extends AbstractConverter<TransactionRequest, Amount>
{
private final ModelMapper mapper;
public TransactionRequestToAmountConverter(ModelMapper mapper)
{
this.mapper = mapper;
}
public Amount convert(TransactionRequest transactionRequest)
{
return mapper.map(transactionRequest, Amount.class);
}
}
public class PurchaseRequestMap extends PropertyMap<TransactionRequest, PurchaseRequest>
{
private final ModelMapper mapper;
public PurchaseRequestMap(ModelMapper mapper)
{
this.mapper = mapper;
}
protected void configure()
{
using(new TransactionRequestToAmountConverter(mapper)).map(source).setAmount(null);
...
}
}
有没有人知道更简单的方法?