Java ModelMapper平面模型到层次模型

时间:2015-01-12 06:37:26

标签: java dto modelmapper

我正在使用www.modelmapper.org,我正在制作相同的" flat" java DTO成几个"层次" DTO。
" flat" 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 to 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 to Amount。此转换器在其构造函数中需要ModelMapper。我传递给构造函数的ModelMapper是从1)
  3. 创建PropertyMap的ModelMapper
  4. 我在PurchaseRequest和CancelRequest的PropertyMaps中使用此转换器
  5. 以下是代码:

    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);
            ...
    
        }
    }
    

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

1 个答案:

答案 0 :(得分:0)

尝试将Long映射到Amount

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

然后该映射将用于您的其他类型,并且应该消除对其他内容的需要(如果我正确地读取您的类型)。