初识Java对象转换工具MapStruct(java 对象转换)

MapStruct解决的问题

在java分层架构中,会出现很多的POJO对象,如DO/DTO/BO/VO,在同一业务不同分层中的传输,或者不同业务中传输,常常需要相互转换。通常情况下,代码中需要大量的 convert类来实现不同领域中对象的转换,而MapStruct可以动态生成代码,来达到不同对象中的转换,而且还支持自定义转换。

DO(Data Object)对象

与数据库表结构一致的类结构,通过DAO层向上传递对象

BO(Business Object)业务对象

封装对象,复杂对象,用于服务层(Manager层)内部调用的对象。可以做业务运算。

DTO(Data Transfer Object)数据传输对象

前端(视图层)调用时传输。

VO 展示层对象

通常由DTO转换而成,而且两者的字段大多数时候是一致的。

一般情况下,DO转DTO,DTO转VO ,VO转DTO、DTO转DO

废话不多说,直接上代码。

Pom.xml

引入依赖,项目配置

mapstruct引入

<properties>
  <org.mapstruct.version>1.4.2.Final</org.mapstruct.version>
</properties>

<dependencies>
  <dependency>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct</artifactId>
        <version>${org.mapstruct.version}</version>
  </dependency>
</dependencies>

maven插件配置

这是动态生成代码的关键


<plugin>
  <groupId>org.apache.maven.plugins</groupId>
  <artifactId>maven-compiler-plugin</artifactId>
  <version>3.8.1</version>
  <configuration>
    <source>1.8</source> <!-- depending on your project -->
    <target>1.8</target> <!-- depending on your project -->
    <annotationProcessorPaths>
      <!--使用lombok的需要配置,不使用的,可以不用配置-->
      <path>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <version>${lombok.version}</version>
      </path>
      <path>
        <groupId>org.mapstruct</groupId>
        <artifactId>mapstruct-processor</artifactId>
        <version>${org.mapstruct.version}</version>
      </path>
      <!-- other annotation processors -->
    </annotationProcessorPaths>
  </configuration>
</plugin>

编写DO类

假设数据库中有一张user表,然后有字段user_name、phone、setting、create_time等

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
public class User {
	private String userName;

	private String phone;
	
	private String setting;

	private Date createTime;
}

编写DTO类

假设dto对象中createTime字段需要的是时间戳

@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@ToString
public class UserDto {
    private String userName;

    private String phone;

    private Long createTime;
}

编写转换类Convert

@Mapper 是MapStruct提供的注解,@Mapping指定转换的方式。

@Mapper
public interface UserConvert {
    UserConvert INSTANCE = Mappers.getMapper( UserConvert.class );

    @Mapping(target = "createTime", expression = "java(user.getCreateTime().getTime())")
    UserDto userToUserDto(User user);
}

编译

编译完成后,会对UserConvert生成其实现类,在target目录中,如下:

public class UserConvertImpl implements UserConvert {
    public UserConvertImpl() {
    }

    public UserDto userToUserDto(User user) {
        if (user == null) {
            return null;
        } else {
            UserDto userDto = new UserDto();
            userDto.setUserName(user.getUserName());
            userDto.setPhone(user.getPhone());
            userDto.setCreateTime(user.getCreateTime().getTime());
            return userDto;
        }
    }
}

测试使用

public static void main(String[] args) {
  User user = new User("name", "18899999999", "{}", new Date());
  UserDto userDto = UserConvert.INSTANCE.userToUserDto(user);
  System.out.println(userDto);
 }

代码输出

UserDto(userName=name, phone=18899999999, createTime=1638076270281)

说明我们的转换生效了。

总结

  • 本文只是入门学习了MapStruct,需要进一步学习的同学可以到MapStruct中学习,链接:https://mapstruct.org/
  • 优点是:代码简洁,可以方便快速避免很多重复的代码。有的时候getter/setter多了会导致手误把属性复制错,这样就不会有这种问题。

本文对MapStruct进行了简单的介绍,如果有不对的地方,还请读者指出。

相关文章

「Java必修课」通过Value获取Map中的键值Key的四种方法

作者:南瓜慢说来源:博客园1 简介我们都知道Map是存放键值对<Key,Value>的容器,知道了Key值,使用方法Map.get(key)能快速获取Value值。然而,有的时候我们需要反...

36.JAVA方法间少用map来传递数据(java mapforeach)

有时候代码上线了才报异常,有次就是因为使用map来传递数据,因为疏忽使线上的功能异常。举个例子:/*赋值**/ public void set() { Map<String,Objec...

Java遍历Map集合有哪几种方式?各自效率怎么样?我来写代码亲测

1、由来我们应该在什么时刻选择什么样的遍历方式呢,必须通过实践的比较才能看到效率,也看了很多文章,大家建议使用entrySet,认为entrySet对于大数据量的查找来说,速度更快,今天我们就通过下面...

遇到MapStruct后,再也不手写PO,DTO,VO对象之间的转换了

介绍在工作中,我们经常要进行各种对象之间的转换。PO:persistent object 持久对象,对应数据库中的一条记录VO:view object 表现层对象,最终返回给前端的对象DTO:data...