【问题标题】:MapStruct Map Object to ListMapStruct 将对象映射到列表
【发布时间】:2019-12-06 05:02:02
【问题描述】:

我正在尝试使用 Mapstruct 将源对象映射到目标列表。什么应该是一个干净的 mapstruct 方式来做到这一点?

以下是我的 DTO。

源 DTO

@Data
class Source
{

String a;

String b;

String C;

}

目标 DTO

@Data
class Target
{

String name;

List<Child> customList;

}

@Data
class Child
{

String attr1;

boolean attr2;

}

我遇到了 Mapper 类的问题。尝试实现以下目标。

public interface CustomMapper
{

@Mapper(target="customList" expression="java(new Child(a,false))"
@Mapper(target="customList"  expression="java(new Child(b,true))"
@Mapper(target="customList"  expression="java(new Child(c,false))"
Target sourceToTarget(Source source);


}

我不想使用下面的qualifiedBy函数来实现这一点,因为所有转换都需要为每个元素编码。

List<Child> toList(Source source)
{
   List<Child> customList = new ArrayList<Child>();
   customList.add(new Child(source.getA(),false));
   customList.add(new Child(source.getB(),true)); 
   customList.add(new Child(source.getC(),false));

    return customList;
}

【问题讨论】:

  • 做,IIUC,列表总是 3 个元素(子)?
  • @Sjaak 不,您的列表可以包含任意数量的元素。在上面的例子中依赖于源 DTO
  • 我的意思是:元素的数量是否取决于类源中的属性数量?所以现在你有了对应于 a、b、c 的三个元素。但是假设你也有 d.. 你的列表会包含 4 个元素吗?这就是我从你的例子中得到的
  • 正确,这取决于类源中的属性数量。
  • 卡在同一个问题上!您通过注释方式解决了您的问题吗?任何痕迹(你是来自 Y****ks 的同一个人吗)

标签: java mapstruct


【解决方案1】:

目前在 MapStruct 中没有干净的方法来执行此操作。 MapStruct 正在考虑 bean tot map 映射。请参阅此处:https://github.com/mapstruct/mapstruct/pull/1744,一旦实施可能会有所帮助。

但是,如果您确实有很多属性并且这是一个反复出现的问题,并且您不喜欢反射 - 就像我一样 - 您可能想要尝试代码生成并 DIY。我前段时间在这里发布了一个用于生成映射器存储库的示例:https://github.com/mapstruct/mapstruct-examples/tree/master/mapstruct-mapper-repo 但是,它的学习曲线有点陡峭.. 抱歉

【讨论】:

    【解决方案2】:

    我有类似的用例,我想将对象的 Single Object 转换为 List。 由于这些是非常定制的要求,mapstruct 很难为这样的用例提供一些 API。

    我最终像这样使用default method 实现

    @Mapper(componentModel = "spring")
    interface MyMapper {
        
        default List<SomeObject> from(SourceObject sourceObject) {
          //Add Mappig logic here 
          //return the list
    
        }
     }
    

    //如果你想使用一些映射器进行映射

    @Mapper(componentModel = "spring")
    public abstract class SomeArrayMapper {
    
        @Autowired
        SomeMapper mapper;
    
        public SomeUser[] from(SingleObject singleObject) {
             SomeUsers[] Users = new SomeUser[1];
             
            Users[0] =  mapper.toUser(singleObject);;
            return Users ;
        }
    }
    

    在某些情况下,装饰器也很有用,看看here

    【讨论】:

      【解决方案3】:

      我使用了一个表达式来解决这个问题。表达式是执行映射(对于对象,直接对于字符串),然后将其转换为列表。

        @Mapping(target = "names", expression = "java(Arrays.asList(map(source.getName())))")
        TargetObject map(SourceObject source);
        
        TargetName map(SourceName source)
      

      您需要在@Mapper 定义中导入“Arrays”类,如下所示。

      @Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = "spring", imports = {Arrays.class})
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-10-12
        • 1970-01-01
        • 2018-01-18
        • 1970-01-01
        • 2016-03-11
        相关资源
        最近更新 更多