JavaBean,Protobuf互相转换

公司使用谷歌的protobuf来进行数据传输,DO 对象对内,DTO对象对外,对于DT与DTO的转换还是手写的build/set,感觉效率太低,所以需要找一个专门用来解决转换问题的工具。

MapStruct 对标的是spring BeanUtilsapache 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);
}

测试结果

upload successful

ProtobufProtocol Buffers)是一种轻量级的数据交换格式,它可以用于结构化数据的序列化和反序列化。而JavaBeanJava语言中的一种编程规范,用于描述一个可重用的Java对象。 在将ProtobufJavaBean进行互时,可以通过以下几个步骤实现: 1. 定义Protobuf消息格式:首先需要定义一个.proto文件,其中定义了消息的字段和类型。例如,定义一个Person消息包含name和age字段: ``` syntax = "proto3"; message Person { string name = 1; int32 age = 2; } ``` 2. 使用Protoc编译器生成Java类:使用Protoc编译器将.proto文件编译成对应的Java类。执行以下命令生成Java类: ``` protoc --java_out=<output_directory> <proto_file>.proto ``` 3. 将Protobuf消息转换JavaBean对象:使用生成的Java类,可以将Protobuf消息转换JavaBean对象。例如,将Person消息转换为对应的JavaBean对象: ```java PersonProto.Person personProto = PersonProto.Person.newBuilder() .setName("John") .setAge(25) .build(); Person person = new Person(); person.setName(personProto.getName()); person.setAge(personProto.getAge()); ``` 4. 将JavaBean对象转换Protobuf消息:反过来,可以将JavaBean对象转换Protobuf消息。例如,将JavaBean对象转换为Person消息: ```java Person person = new Person(); person.setName("John"); person.setAge(25); PersonProto.Person.Builder personProtoBuilder = PersonProto.Person.newBuilder() .setName(person.getName()) .setAge(person.getAge()); PersonProto.Person personProto = personProtoBuilder.build(); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值