【问题标题】:MapStruct nested list source to flatten targetMapStruct 嵌套列表源以展平目标
【发布时间】:2021-12-09 06:13:24
【问题描述】:

如何映射以下内容:

class Source {
   String name;
   List<Other> others;
}
class Other {
   String otherName;
   List<More> mores;
}
class More {
   String moreName;
}

class Target {
   String name;
   String otherName;
   String moreName;
}

希望它可能是这样的:

@Mapper
public interface MyMapper {

    @Mapping(target = "name", source = "name")
    @Mapping(target = "otherName", source = "others[0].otherName")
    @Mapping(target = "morename", source = "others[0].mores[0].moreName")
    Target map(Source source);

我看到 'expression = "java(others.get(0).otherName)"' 可以使用,但是使用表达式时没有空检查,这可能会导致 NullPointeException。可以应用任何带有空检查和默认值的建议吗?

【问题讨论】:

    标签: java spring spring-boot mapstruct


    【解决方案1】:

    我想你需要看看这个例子:MapStruct String to List mapping

    基本上,你需要在获取一些元素之前验证列表的大小。

    【讨论】:

      【解决方案2】:

      你可以使用expression检查空值并返回一些东西。

      @Mapper
      public interface MyMapper {
          @Mapping(target = "name", source = "name")
          @Mapping(target = "otherName", expression = "java(s.others != null && !s.others.isEmpty() ? s.others.get(0).otherName : \"\")")
          @Mapping(target = "moreName", expression = "java(s.others != null && !s.others.isEmpty() && s.others.get(0).mores != null && !s.others.get(0).mores.isEmpty() ? s.others.get(0).mores.get(0).moreName : \"\")")
          Target map(Source s);
      }
      
      // mapstruct code generate.
      public class MyMapperImpl implements MyMapper {
          @Override
          public Target map(Source s) {
              if ( s == null ) {
                  return null;
              }
      
              Target target = new Target();
      
              target.name = s.name;
      
              target.otherName = s.others != null && !s.others.isEmpty() ? s.others.get(0).otherName : "";
              target.moreName = s.others != null && !s.others.isEmpty() && s.others.get(0).mores != null && !s.others.get(0).mores.isEmpty() ? s.others.get(0).mores.get(0).moreName : "";
      
              return target;
          }
      }
      

      如果想要可读性和减少校验空重复代码,可以使用接口default方法,使用org.springframework.util.ObjectUtils.isEmpty()

      @Mapper
      public interface MyMapper {
          @Mapping(target = "name", source = "name")
          @Mapping(target = "otherName", expression = "java(getFirstOtherName(s))")
          @Mapping(target = "moreName", expression = "java(getFirstMoreName(s))")
          Target map(Source s);
      
          default String getFirstOtherName(Source s) {
              return !ObjectUtils.isEmpty(s.others) ? s.others.get(0).otherName : "";
          }
      
          default String getFirstMoreName(Source s) {
              return !ObjectUtils.isEmpty(s.others) && !ObjectUtils.isEmpty(s.others.get(0).mores) ? s.others.get(0).mores.get(0).moreName : "";
          }
      }
      
      // mapstruct code generate.
      public class MyMapperImpl implements MyMapper {
      
          @Override
          public Target map(Source s) {
              if ( s == null ) {
                  return null;
              }
      
              Target target = new Target();
      
              target.name = s.name;
      
              target.otherName = getFirstOtherName(s);
              target.moreName = getFirstMoreName(s);
      
              return target;
          }
      } 
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2018-07-04
        • 2020-10-11
        • 1970-01-01
        • 1970-01-01
        • 2017-11-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多