我们使用 immutables framework生成所有DTO.现在我们想用 mapstruct将这些对象映射到另一个.但生成的DTO是不可变的,没有setter,也没有构造函数,对应于builder模式.它们仅通过静态builder() – 方法访问的相应构建器填充.

我们试图将DTO1映射到DTO2.Builder,如果mapstruct能识别Builder中的setter但这些没有void返回类型但返回Builder本身以进行流畅的连接,那么它将起作用.

所以这是示例的代码.

我们有两个接口

@Value.Immutable
public interface MammalDto {
  public Integer getNumberOfLegs();
  public Long getNumberOfStomachs();
}

@Value.Immutable
public interface MammalEntity {
  public Long getNumberOfLegs();
  public Long getNumberOfStomachs();
}

然后我们有了maptruct的Mapper接口:

@Mapper(uses = ObjectFactory.class)
public interface SourceTargetMapper {
  SourceTargetMapper MAPPER = Mappers.getMapper( SourceTargetMapper.class );

  ImmutableMammalEntity.Builder toTarget(MammalDto source);
}

要使mapORG找到Builder,我们需要一个Factory:

public class ObjectFactory {

  public ImmutableMammalDto.Builder createMammalDto() {
    return ImmutableMammalDto.builder();
  }

  public ImmutableMammalEntity.Builder createMammalEntity() {
    return ImmutableMammalEntity.builder();
  }
}

为了生成代码,编译器插件被指示使用两个注释处理器:

<plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>3.6.1</version>
    <configuration>
        <source>1.8</source>
        <target>1.8</target>
        <annotationProcessorPaths>
            <path>
                <groupId>org.immutables</groupId>
                <artifactId>value</artifactId>
                <version>2.2.8</version>
            </path>
            <path>
                <groupId>org.mapstruct</groupId>
                <artifactId>mapstruct-processor</artifactId>
                <version>1.2.0.Beta3</version>
            </path>
        </annotationProcessorPaths>
    </configuration>
</plugin>

注意:这仅适用于mapstruct版本> 1.2.x.旧版本在干净构建(mvn clean compile)中存在问题,即它们找不到不可变构建的源.在第二个构建(没有干净)中,他们会找到immutables实现,因为它们在注释处理器运行之前位于类路径中.这个bug现在已修复.

这就像一个魅力.首先生成interfactes的Immutable实现,并且mapstruct使用它们来生成构建器.

但测试表明没有设置属性:

@Test
public void test() {
  MammalDto s = ImmutableMammalDto.builder().numberOfLegs(4).numberOfStomachs(3l).build();
  MammalEntity t = SourceTargetMapper.MAPPER.toTarget(s).build();
    assertthat(t.getNumberOfLegs()).isEqualTo(4);
    assertthat(t.getNumberOfStomachs()).isEqualTo(3);
}

断言失败.一看maptruct生成的mapper就会发现它显然没有找到任何setter:

@Generated(
    value = "org.mapstruct.ap.MappingProcessor",//...
)
public class SourceTargetMapperImpl implements SourceTargetMapper {
    private final ObjectFactory objectFactory = new ObjectFactory();

    @Override
    public Builder toTarget(MammalDto source) {
        if ( source == null ) {
            return null;
        }

        Builder builder = objectFactory.createMammalEntity();
        return builder;
    }
}

返回空构建器.我认为原因是生成的构建器的setter实现,因为它返回自身以创建一个流畅的API:

public final Builder numberOfLegs(Long numberOfLegs) {
  this.numberOfLegs = Objects.requireNonNull(numberOfLegs,"numberOfLegs");
  return this;
}

有没有办法让mapstruct找到这些setter?或者甚至是用构建器处理这些不可变对象的更好方法?

编辑:正如我在评论中所说,我遇到了Issue #782.在版本1.2.0.Beta3建设者仍然不支持.但是关于这个主题有几个讨论,所以如果一个人遇到同样的问题,可能会有兴趣.

解决方法

我们的项目也有同样的问题.
作为解决方法,我们一直在使用不可变dto的可修改实现.

你也可以尝试一下.直接使用构建器和对象工厂更好.

@ Value.Modifiable使用setter生成实现.

@ Value.Style(create =“new”)生成public no args构造函数.

@Value.Immutable
@Value.Modifiable
@Value.Style(create = "new")
public interface MammalEntity {
    public Long getNumberOfLegs();
    public Long getNumberOfStomachs();
}

那么你的映射器将更简单,不需要在对象工厂中.

@Mapper
public interface SourceTargetMapper {

  ModifiableMammalEntity toTarget(MammalDto source);
}

在这种情况下,MapStruct可以在ModifiableMammalEntity中看到setter

这种映射器的用法看起来像

// Here you don't need to worry about implementation of MammalEntity is. The interface `MammalEntity` is immutable.
MammalEntity mammalEntity = sourceTargetMapper.toTarget(source);

java – 使用mapstruct中的builder(使用immutables注释处理器)将对象映射到不可变对象的更多相关文章

  1. 使用 Swift语言进行 Hadoop 数据流应用程序开发

    如果您发现了问题,或者希望为改进本文提供意见和建议,请在这里指出.在您开始之前,请参阅目前待解决的问题清单.简介本项目包括两类Hadoop流处理应用程序:映射器mapper和总结器reducer。如上所示,在Hadoop上编写流处理程序是一个很简单的工作,也不需要依赖于特定的软件体系。

  2. android – JacksonParser数据绑定和核心导致“找到APK的重复文件”?

    有什么我做错了吗?

  3. Mybatis generator修改Mapper.java文件实现详解

    这篇文章主要为大家介绍了Mybatis generator修改Mapper.java文件实现详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. mapper--图片热点区域高亮组件官方站点

    mapper--图片热点区域高亮组件官方站点

  5. MyBatis源码剖析之Mapper代理方式详解

    这篇文章主要为大家详细介绍了MyBatis中Mapper代理的方式,文中将通过源码为大家进行详细的剖析,感兴趣的小伙伴可以跟随小编一起学习一下

  6. SpringBoot快速整合通用Mapper的示例代码

    后端业务开发,每个表都要用到单表的 增删改查 等通用方法,而配置了通用Mapper可以极大的方便使用Mybatis单表的增删改查操作,这篇文章主要介绍了SpringBoot快速整合通用Mapper,需要的朋友可以参考下

  7. springboot实现指定mybatis中mapper文件扫描路径

    这篇文章主要介绍了springboot实现指定mybatis中mapper文件扫描路径方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  8. MyBatis映射器mapper快速入门教程

    使用mapper接口的方式,不用写接口实现类,直接完成数据库操作,简单方便。使用mapper接口,采用的是面向接口编程的思想,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧

  9. Idea工具中使用Mapper对象有红线的解决方法

    mapper对象在service层有红线,项目可以正常使用,想知道为什么会出现这种情,接下来通过本文给大家介绍下Idea工具中使用Mapper对象有红线的问题,需要的朋友可以参考下

  10. 在jbd2 / dm-0-8上的CentOS6和长等待IO时间

    运行CentOS6.5和2.6.32-431.3.1.el6.i686内核的Linux机箱最近因WaitIO而导致cpu峰值高达99%.执行给我这些cpu峰值:所以它让我认为这些峰值的来源是Journaldisk.我发现该主题类似IOWaitcausingsomuchslowdown(EXT4JDB2at99%IO)DuringMysqlCommit,但我不知道如果我的分区是日记数据,我可以找到.

随机推荐

  1. 基于EJB技术的商务预订系统的开发

    用EJB结构开发的应用程序是可伸缩的、事务型的、多用户安全的。总的来说,EJB是一个组件事务监控的标准服务器端的组件模型。基于EJB技术的系统结构模型EJB结构是一个服务端组件结构,是一个层次性结构,其结构模型如图1所示。图2:商务预订系统的构架EntityBean是为了现实世界的对象建造的模型,这些对象通常是数据库的一些持久记录。

  2. Java利用POI实现导入导出Excel表格

    这篇文章主要为大家详细介绍了Java利用POI实现导入导出Excel表格,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  3. Mybatis分页插件PageHelper手写实现示例

    这篇文章主要为大家介绍了Mybatis分页插件PageHelper手写实现示例,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  4. (jsp/html)网页上嵌入播放器(常用播放器代码整理)

    网页上嵌入播放器,只要在HTML上添加以上代码就OK了,下面整理了一些常用的播放器代码,总有一款适合你,感兴趣的朋友可以参考下哈,希望对你有所帮助

  5. Java 阻塞队列BlockingQueue详解

    本文详细介绍了BlockingQueue家庭中的所有成员,包括他们各自的功能以及常见使用场景,通过实例代码介绍了Java 阻塞队列BlockingQueue的相关知识,需要的朋友可以参考下

  6. Java异常Exception详细讲解

    异常就是不正常,比如当我们身体出现了异常我们会根据身体情况选择喝开水、吃药、看病、等 异常处理方法。 java异常处理机制是我们java语言使用异常处理机制为程序提供了错误处理的能力,程序出现的错误,程序可以安全的退出,以保证程序正常的运行等

  7. Java Bean 作用域及它的几种类型介绍

    这篇文章主要介绍了Java Bean作用域及它的几种类型介绍,Spring框架作为一个管理Bean的IoC容器,那么Bean自然是Spring中的重要资源了,那Bean的作用域又是什么,接下来我们一起进入文章详细学习吧

  8. 面试突击之跨域问题的解决方案详解

    跨域问题本质是浏览器的一种保护机制,它的初衷是为了保证用户的安全,防止恶意网站窃取数据。那怎么解决这个问题呢?接下来我们一起来看

  9. Mybatis-Plus接口BaseMapper与Services使用详解

    这篇文章主要为大家介绍了Mybatis-Plus接口BaseMapper与Services使用详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  10. mybatis-plus雪花算法增强idworker的实现

    今天聊聊在mybatis-plus中引入分布式ID生成框架idworker,进一步增强实现生成分布式唯一ID,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

返回
顶部