MapStruct 将对象映射到列表

Nir*_*pta 8 java mapstruct

我正在尝试使用 Mapstruct 将源对象映射到目标列表。执行此操作的干净映射结构方式应该是什么?

以下是我的 DTO。

源DTO

@Data
class Source
{

String a;

String b;

String C;

}

Run Code Online (Sandbox Code Playgroud)

目标DTO

@Data
class Target
{

String name;

List<Child> customList;

}

@Data
class Child
{

String attr1;

boolean attr2;

}

Run Code Online (Sandbox Code Playgroud)

我面临映射器类的问题。试图实现如下所示的目标。

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


}
Run Code Online (Sandbox Code Playgroud)

我不想使用如下所示的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;
}
Run Code Online (Sandbox Code Playgroud)

小智 9

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

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

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

@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = "spring", imports = {Arrays.class})
Run Code Online (Sandbox Code Playgroud)


Nir*_*ane 5

我有类似的用例,我想将对象转换Single ObjectList对象。由于这些是非常自定义的需求,因此很难为mapstruct此类用例提供一些 API。

我最终使用default method这样的方式实现

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

    }
 }
Run Code Online (Sandbox Code Playgroud)

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

@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 ;
    }
}
Run Code Online (Sandbox Code Playgroud)

在某些情况下,装饰器也很有用,请看这里


Sja*_*aak 2

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

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