公司使用谷歌的protobuf
来进行数据传输,DO 对象对内,DTO对象对外,对于DT与DTO的转换还是手写的build/set,感觉效率太低,所以需要找一个专门用来解决转换问题的工具。
MapStruct 对标的是spring BeanUtils
和apache BeanUtil
,但是性能却比这两种好上许多倍。 官网:MapStruct是一个用于生成类型安全、性能良好且无依赖项的bean映射代码的注释处理器
MapStruct 就是这样的一个属性映射工具,且效率比BeanUtil高很多,只需要定义一个 Mapper 接口,MapStruct 就会自动实现这个映射接口,避免了复杂繁琐的映射实现。MapStruct官网地址: http://mapstruct.org/
DO(业务实体对象),DTO(数据传输对象
- 接口传入的对象和返回的对象字段名字匹配且类型匹配时,在编译时自动生成对应的转换方法
- 生成的转换实现类在target包(maven项目)下接口同级目录
- 转换写法有误会导致编译无法通过,请根据提示修改
依赖引入
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.ypshengxian.ostrich</groupId>
<artifactId>ostrich-core</artifactId>
<version>1.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>${org.mapstruct.version}</version>
</dependency>
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
<version>3.6.1</version>
</dependency>
<dependency>
<groupId>no.entur.mapstruct.spi</groupId>
<artifactId>protobuf-spi-impl</artifactId>
<version>1.8</version>
</dependency>
<dependency>
<groupId>com.ypshengxian</groupId>
<artifactId>ypsx-common-core</artifactId>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
</extension>
</extensions>
<plugins>
<plugin>
<groupId>org.xolstice.maven.plugins</groupId>
<artifactId>protobuf-maven-plugin</artifactId>
<version>0.5.1</version>
<configuration>
<protocArtifact>com.google.protobuf:protoc:3.6.1:exe:${os.detected.classifier}</protocArtifact>
<pluginId>grpc-java</pluginId>
<pluginArtifact>io.grpc:protoc-gen-grpc-java:1.19.0:exe:${os.detected.classifier}</pluginArtifact>
</configuration>
<executions>
<execution>
<goals>
<goal>compile</goal>
<goal>compile-custom</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
@Mapper注解
@Mapper(/* 用于 Spring 注入 */
componentModel = "spring",
/* PB <-> JavaBean 模式下使用该策略 */
collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
/* 未映射目标属性的报告策略 */
unmappedTargetPolicy = ReportingPolicy.IGNORE,
/* 确定何时对bean映射的源属性值包含空检查 */
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
Proto
syntax = "proto3";
package com.ypshengxian.store.proto;
import "Error.proto";
import "google/protobuf/timestamp.proto";
option java_package = "com.ypshengxian.domain";
option java_outer_classname = "StoreCartProtos";
service StoreCartService {
// 购物车列表
rpc list (ListCarRequest) returns (CartInfoResponse);
}
message ListCarRequest {
// 门店ID
int64 shopId = 1;
// 营业部Id
int64 businessDepartmentId = 2;
// 换购商品列表 普通商品为0 换购商品为1
int32 businessType = 3;
}
Java对象
@Data
@AllArgsConstructor
@NoArgsConstructor
@Builder
public class ListCarRequestEntity {
long shopId;
long departmentId;
int businessType;
}
转换Mapper
package com.ypshengxian.mapper;
import com.ypshengxian.common.baseInterface.BaseMapper;
import com.ypshengxian.domain.ListCarRequestEntity;
import com.ypshengxian.domain.StoreCartProtos;
import org.mapstruct.*;
import org.mapstruct.factory.Mappers;
/**
* 描述:
* Created by zjw on 2021/8/8 13:15
*/
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
unmappedTargetPolicy = ReportingPolicy.IGNORE,
nullValueCheckStrategy = NullValueCheckStrategy.ON_IMPLICIT_CONVERSION)
public interface CartMapper extends BaseMapper<ListCarRequestEntity> {
CartMapper CART_MAPPER_INSTANCE = Mappers.getMapper(CartMapper.class);
/**
* 不同字段转换
*/
@Override
@Mapping(source = "requestEntity.departmentId", target = "businessDepartmentId")
StoreCartProtos.ListCarRequest dto(ListCarRequestEntity requestEntity);
@Mapping(source = "request.businessDepartmentId", target = "departmentId")
ListCarRequestEntity request(StoreCartProtos.ListCarRequest request);
}