【问题标题】:Java Object mapping framework working with builder pattern使用构建器模式的 Java 对象映射框架
【发布时间】:2017-10-02 17:08:51
【问题描述】:

是否有任何适用于构建器的类映射框架?我想保持我的一些类不可变并避免使用多个构造函数 - 构建器模式来拯救。但是,我不能使用任何会自动使用构建器而不是 getter/setter 的映射框架。

【问题讨论】:

  • 我不确定您的确切要求,但 Project Lombok 可能值得一看...

标签: java mapping dozer mapstruct modelmapper


【解决方案1】:

我使用LombokModelMapper 完成了以下工作。见:http://modelmapper.org/getting-started/

public class MyService {
     private ModelMapper modelMapper;

     public MyService(){
         this.modelMapper = new ModelMapper();
         this.modelMapper.getConfiguration()
            .setMatchingStrategy(MatchingStrategies.STRICT)
            .setDestinationNamingConvention(LombokBuilderNamingConvention.INSTANCE)
            .setDestinationNameTransformer(LombokBuilderNameTransformer.INSTANCE);
     }

     public OutputDTO aMethod(final InputDTO input){
          return modelMapper.map(input, OutputDTO.OutputDTOBuilder.class).build(); 
     }
}

LombokBuilderNamingConvention 在哪里:

import org.modelmapper.spi.NamingConvention;
import org.modelmapper.spi.PropertyType;

public class LombokBuilderNamingConvention implements NamingConvention {

    public static LombokBuilderNamingConvention INSTANCE = new LombokBuilderNamingConvention();

    @Override
    public boolean applies(String propertyName, PropertyType propertyType) {
        return PropertyType.METHOD.equals(propertyType);
    }

    @Override
    public String toString() {
        return "Lombok @Builder Naming Convention";
    }

}

LombokBuilderNameTransformer 是:

import org.modelmapper.spi.NameTransformer;
import org.modelmapper.spi.NameableType;


public class LombokBuilderNameTransformer implements NameTransformer {

    public static final NameTransformer INSTANCE = new LombokBuilderNameTransformer();

    @Override
    public String transform(final String name, final NameableType nameableType) {
        return Strings.decapitalize(name);
    }

    @Override
    public String toString() {
        return "Lombok @Builder Mutator";
    }
}

OutputDTO 看起来像:

@Builder // Has .builder() static method
@Value // Thus immutable
public class OutputDTO {
   private String foo;
   private int bar;
} 

【讨论】:

    【解决方案2】:

    这可以通过 MapStruct 和为构建器使用自定义命名策略轻松完成。

    在文档中查看here 如何使用自定义访问器命名策略。

    然后您的映射需要如下所示:

    @Mapper
    public interface MyMapper {
    
        default Immutable map(Source source) {
            return mapToBuilder(source).build();
        }
    
        Immutable.Builder mapToBuilder(Source source);
    }
    

    在 MapStruct 中,我们已经在开发一项支持对构建器的开箱即用支持的功能。您可以关注this issue 了解更多详情。

    更新

    MapStruct 现在(从 1.3.0.Beta1 开始)对不可变对象提供了开箱即用的支持。这意味着之前的映射器可以写成这样:

    @Mapper
    public interface MyMapper {
    
        Immutable map(Source source);
    }
    

    假设Immutable中有一个不带参数的公共静态方法返回builder

    【讨论】:

      猜你喜欢
      • 2013-09-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多