Java中使用MapStruct实现对象转换/实体属性赋值/Bean属性映射,避免大量setter和getter

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

场景

开发过程中会有一些实体转换的需求有的属性差不多即使两个实体对象拥有同名

的属性也需要调用get和set进行取值赋值。比如下面这样:

                longTimeNoLoginList.forEach(busMailList -> {
                    BusDriverNoLoginRecord busDriverNoLoginRecord = new BusDriverNoLoginRecord();
                    busDriverNoLoginRecord.setCarNum(busMailList.getCarNumber());
                    busDriverNoLoginRecord.setNoLoginType(DriverNoLoginTypeEnum.LONGAGOLOGIN.getCode());
                    busDriverNoLoginRecord.setRecordTime(new Date());
                    busDriverNoLoginRecord.setLastLoginNumber(busMailList.getDriverNumber());
                    busDriverNoLoginRecord.setLastLoginTime(null == busMailList.getBindingTime()?busMailList.getUpdateTime():busMailList.getBindingTime());
                });

上面只是两个业务上对象的部分属性需要进行取值赋值操作更多场景下还有同一个业务模块下VO、DTO、BO、PO、DAO等的转换。

 

MapStruct

MapStruct – Java bean mappings, the easy way!

 

看一下官方的说明Java bean的映射更简单的方式。

博客
https://blog.csdn.net/badao_liumang_qizhi 

实现

1、依赖引入

        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
            <version>1.4.2.Final</version>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
            <version>1.4.2.Final</version>
        </dependency>

2、先看一下官网给出的使用示例

新建Car.java以及CarDto.java

public class Car {
 
    private String make;
    private int numberOfSeats;
    private CarType type;
 
    //constructor, getters, setters etc.
}
public class CarDto {
 
    private String make;
    private int seatCount;
    private String type;
 
    //constructor, getters, setters etc.
}

然后新建转换接口类并添加@Mapper注解

@Mapper 1
public interface CarMapper {
 
    CarMapper INSTANCE = Mappers.getMapper( CarMapper.class ); 3
 
    @Mapping(source = "numberOfSeats", target = "seatCount")
    CarDto carToCarDto(Car car); 2
}

如果需要转换的属性不同命通过

@Mapping(source = "numberOfSeats", target = "seatCount")

进行映射。

然后测试转换

@Test
public void shouldMapCarToDto() {
    //given
    Car car = new Car( "Morris", 5, CarType.SEDAN );
 
    //when
    CarDto carDto = CarMapper.INSTANCE.carToCarDto( car );
 
    //then
    assertThat( carDto ).isNotNull();
    assertThat( carDto.getMake() ).isEqualTo( "Morris" );
    assertThat( carDto.getSeatCount() ).isEqualTo( 5 );
    assertThat( carDto.getType() ).isEqualTo( "SEDAN" );
}

3、下面在自己的业务中实现

若依前后端分离版本地搭建开发环境并运行项目的教程

若依前后端分离版手把手教你本地搭建环境并运行项目_霸道流氓气质的博客-CSDN博客_若依前后端分离项目本地运行

在上面搭建框架的基础上并添加依赖后新建转换接口

import com.ruoyi.common.core.domain.basicinfomanage.BusMailList;
import com.ruoyi.common.core.domain.reportmanagement.BusDriverNoLoginRecord;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.Mappings;
import org.mapstruct.factory.Mappers;

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

    @Mappings({
            @Mapping(source = "carNumber",target = "carNum"),
            @Mapping(source = "driverNumber",target = "lastLoginNumber")
    })
    BusDriverNoLoginRecord mailList2NoLoginRecord(BusMailList busMailList);
}

注意这里引入的Mapper、Mapping、Mappings的包路径。

然后前面两个引入的实体类是需要转换的对象下面方法中@Mappings代表需要将

BusMailList的carNumber转换到BusDriverNoLoginRecord的carNum以及

BusMailList的driverNumber转换到BusDriverNoLoginRecord的lastLoginNumber

具体需要转换的规则自己根据业务需求去配置如果同名会默认进行转换

这里只配置了两个不同名的属性。

如果同名的属性但是不需要进行转换的话比如id属性可以添加ignore=true来配置

    @Mappings({
            @Mapping(source = "carNumber",target = "carNum"),
            @Mapping(source = "driverNumber",target = "lastLoginNumber"),
            @Mapping(target = "id",ignore = true)
    })

那么上面的具体业务调用就可以修改为

                longTimeNoLoginList.forEach(busMailList -> {
                    BusDriverNoLoginRecord busDriverNoLoginRecord = DriverNoLoginConvert.INSTANCE.mailList2NoLoginRecord(busMailList);
                });

测试之后发现转换成功

 

4、注意事项

如果在引入pom依赖之后打包时提示

MapStruct - Couldn‘t retrieve @Mapper annotation

 

这是因为与 springfox-swagger2 冲突该框架里也包含 mapstruct在swagger2中排除掉

        <dependency>
            <groupId>io.springfox</groupId>
            <artifactId>springfox-swagger2</artifactId>
            <version>${swagger.fox.version}</version>
            <scope>compile</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.mapstruct</groupId>
                    <artifactId>mapstruct</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

 

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: Java