0

我正在使用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 时使用映射机制。然而事实并非如此。

我尝试的第二件事确实有效,但似乎过于复杂:

  1. 我为 TransactionRequest 到 Amount 的映射创建了一个 PropertyMap。
  2. 我创建了一个自定义转换器 TransactionRequest 到 Amount。此转换器在其构造函数中需要一个 ModelMapper。我传递给构造函数的 ModelMapper 是从 1) 创建 PropertyMap 的 ModelMapper
  3. 我在 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);
        ...

    }
}

有没有人知道更简单的方法?

4

1 回答 1

0

尝试自己映射LongAmount

modelMapper.createTypeMap(Long.class, Amount.class).setConverter(new Converter<Long, Amount>() {
  //... convert Long to Amount
});

然后,该映射将用于您的其他类型,并且应该消除对其他东西的需求(如果我正确阅读了您的类型)。

于 2015-01-13T18:48:20.973 回答