1 MapStruct是什么
MapStruct是一个代码生成器,它基于约定优于配置的方法大大简化了Java Bean类型之间的映射的实现。
生成的映射代码使用简单的方法调用,因此速度快,类型安全且易于理解。
它有什么用?
多层应用程序通常需要在不同的对象模型之间进行映射。比如VO对象向DTO对象的转换,DTO对象向PO对象的转换,编写这些转换代码是一项繁琐且容易出错的任务。MapStruct旨在通过使其尽可能自动化来简化这项工作。
VO(View Object):视图对象,用于视图层,它的作用是接收用户界面传过来的参数进行封装。
DTO(Data Transfer Object):数据传输对象,这个概念来源于J2EE的设计模式,传统的三层架构即控制层、业务层、持久层,DTO对象用于视图层与服务层之间的数据传输对象。
PO(Persistent Object):持久化对象,它跟持久层(通常是关系型数据库)的数据结构形成一一对应的映射关系,如果持久层是关系型数据库,那么,数据表中的每个字段(或若干个)就对应PO的一个(或若干个)属性。
下边是没有使用MapStruct的代码:
@GetMapping("/test")
public String test(UserVo userVo){
//将vo转为dto
UserDto userDto = new UserDto();
userDto.setId(userVo.getId());
userDto.setName(userVo.getFullname());
userDto.setBirthday(userVo.getBirthday());
//...
return userService.test(userDto);
}
下边是使用MapStruct的代码:
@GetMapping("/test")
public String test(UserVo userVo){
//将vo转为dto
UserDto userDto = UserConvert.INSTANCE.vo2dto(userVo);
return userService.test(userDto);
}
使用了MapStruct只需要一行代码!!!
2 一个例子
本例子是基于SpringBoot开发,分别编写一个controller和service,实现vo转dto。
完整的代码:
https://download.csdn.net/download/weixin_44062339/11989206
或
链接:https://pan.baidu.com/s/1km3B1YLZQ9aXTuC8GvrWpA
提取码:xnhc
2.1添加依赖
创建工程,并在pom.xml添加依赖:
<dependencies>
<!--springmvc依赖-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--mapStruct相关依赖-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<!--mapStruct相关依赖-->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<!--lombok依赖,也是一个神器-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</dependency>
</dependencies>
完整的pom.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
</parent>
<groupId>com.pbteach.java</groupId>
<artifactId>mapstruct_test</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<org.projectlombok.version>1.18.0</org.projectlombok.version>
<org.mapstruct.version>1.3.0.Final</org.mapstruct.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-jdk8</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${org.projectlombok.version}</version>
</dependency>
</dependencies>
<build>
<finalName>${project.name}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
<includes>
<include>**/*</include>
</includes>
</resource>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
<plugin>
<artifactId>maven-resources-plugin</artifactId>
<configuration>
<encoding>utf-8</encoding>
<useDefaultDelimiters>true</useDefaultDelimiters>
</configuration>
</plugin>
</plugins>
</build>
</project>
2.2 vo和dto
定义vo和dto
UserVo:
@Data//lombok注解,省去getter/setter
@ToString//lombok注解,省去toString方法
public class UserVo {
private String id;
private String fullname;
private Date birthday;
private String password;
private String repepassword;
}
UserDto:
@Data
@ToString
public class UserDto {
private String id;
private String name;
private Date birthday;
private String password;
private String repepassword;
private String city;
private String address;
}
UserDetailVo:
/**
* @author www.pbteach.com
* @version 1.0
**/
@Data
@ToString
public class UserDetailVo {
private String city;
private String address;
}
2.3 编写convert
使用MapStruct需要编写convert接口:
重点看这些注解:@Mapper、 @Mappings 、 @Mapping
package com.pbteach.java.mapstruct.model.convert;
import com.pbteach.java.mapstruct.model.UserDetailVo;
import com.pbteach.java.mapstruct.model.UserDto;
import com.pbteach.java.mapstruct.model.UserVo;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;
@Mapper//接口上加此注解mapstruct自动实现该接口
public interface UserConvert {
UserConvert INSTANCE = Mappers.getMapper(UserConvert.class);
/**
* 一个对象映射为一个对象
@Mapping:属性映射,当源对象属性与目标对象属性名一致时无需定义,否则需要定义映射对应的属性
source:源属性
target:目标属性
*/
@Mappings({
@Mapping(source = "fullname", target = "name")
})
UserDto vo2dto(UserVo vo);
//两个对象映射为一个对象
@Mappings({
@Mapping(source = "vo.fullname", target = "name")
})
UserDto vo2dto(UserVo vo, UserDetailVo userDetailVo);
//dto转成vo
@Mappings({
@Mapping(source = "name", target = "fullname")
})
UserVo dto2vo(UserDto dto);
}
2.4 Service
service很简单,就是输出dto对象的属性:
/**
* @author www.pbteach.com
* @version 1.0
**/
@Service
public class UserService {
public String test(UserDto userDto){
//调用dao...使用vo转dto的方法将Dto转为Po...
return userDto.toString();
}
}
2.5 Controller
Controller实现接收请求参数,将vo转成dto调用service
package com.pbteach.java.mapstruct.controller;
import com.pbteach.java.mapstruct.model.UserDetailVo;
import com.pbteach.java.mapstruct.model.UserDto;
import com.pbteach.java.mapstruct.model.UserVo;
import com.pbteach.java.mapstruct.model.convert.UserConvert;
import com.pbteach.java.mapstruct.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @author www.pbteach.com
* @version 1.0
**/
@RestController
public class UserController {
@Autowired
UserService userService;
//将一个对象转一个对象
@GetMapping("/test")
public String test(UserVo userVo){
//将vo转为dto
UserDto userDto = UserConvert.INSTANCE.vo2dto(userVo);
return userService.test(userDto);
}
//将多个对象转一个对象
@GetMapping("/test2")
public String test2(UserVo userVo, UserDetailVo userDetailVo){
UserDto userDto = UserConvert.INSTANCE.vo2dto(userVo,userDetailVo);
return userService.test(userDto);
}
}
2.6 测试
请求:http://localhost:8080/test?id=11&fullname=pbteach&city=zz测试一个对象转一个对象
请求:http://localhost:8080/test2?id=11&fullname=pbteach&city=zz测试多个对象转一个对象