MapStruct一个代码的装潢师

1.什么是MapStruct?

1.1 MapStruct

MapStruct官网

MapStruct是一个代码生成器,它基于约定优于配置的方法,极大地简化了Java bean类型之间映射的实现。生成的映射代码使用简单的方法调用,因此快速、类型安全且易于理解。
在装修房屋时,一些排线尽可能的走内线,注意会让房间显得更加整洁,美观。 MapStruct像一位代码的装修专家,简化Java Bean的转换。

1.2 添加依赖

 <dependency>
  	   <groupId>org.mapstruct</groupId>
         <artifactId>mapstruct</artifactId>
       <version>1.3.1.Final</version>
  </dependency>

2.应用场景

2.1 字段名称相等转换

2.1.1 单个对象转换

转换mapper

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
...

@Mapper(componentModel = "spring")
public interface StudentMapper {
    
    
    /**
     * 转 responseDto
     * @param s
     * @return
     */
    StudentResponseDTO entityToResponseDTO(Student s);
}

转换前Student实体类

{
    
    
    "age": 24,
    "className": "一年级五班",
    "entranceTime": "2022-10-18",
    "height": 180.0,
    "name": "我玩亚索我会C",
    "weight": 140.0
}

转换后StudentResponseDTO

{
    
    
    "className": "一年级五班",
    "name": "我玩亚索我会C"
}

2.1.2 集合转换

转换Mapper

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;

@Mapper(componentModel = "spring")
public interface StudentMapper {
    
    
    /**
     * 转 responseDto list
     * @return
     */
    List<StudentResponseDTO> listEntityToResponseListDto(List<Student> studentes);
}

转换前Student List集合

[
    {
    
    
        "age": 24,
        "className": "一年级五班",
        "height": 180.0,
        "name": "我玩亚索我会C",
        "weight": 140.0
    },
    {
    
    
        "age": 25,
        "className": "铃兰五班",
        "height": 184.0,
        "name": "泷谷源治",
        "weight": 130.0
    },
    {
    
    
        "age": 26,
        "className": "铃兰一班",
        "height": 178.0,
        "name": "芹泽多摩雄",
        "weight": 160.0
    },
    {
    
    
        "age": 24,
        "className": "铃兰火箭班",
        "height": 175.0,
        "name": "辰川时生",
        "weight": 120.0
    }
]

转换后 StudentResponseDTO 集合

[
    {
    
    
        "className": "一年级五班",
        "name": "我玩亚索我会C"
    },
    {
    
    
        "className": "铃兰五班",
        "name": "泷谷源治"
    },
    {
    
    
        "className": "铃兰一班",
        "name": "芹泽多摩雄"
    },
    {
    
    
        "className": "铃兰火箭班",
        "name": "辰川时生"
    }
]

2.2 字段不相等转换

2.2.1 单个对象转换

当被转换的对象中的属性名称和转换的对象中的属性名称不相等时,使用注解 @Mapping 来手动映射,target 表示目标,source表示源头,手动映射就是将source中的属性, 映射到target 中的属性。

转换Mapper

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
...

@Mapper(componentModel = "spring")
public interface StudentMapper {
    
    
    /**
     * 转实体
     * @param dto
     * @return
     */
    @Mapping(target = "name",source = "studentName")
    @Mapping(target = "className",source = "studentClassName")
    Student requestDTOToEntity(StudentRequestDTO dto);
}

转换前StudentRequestDTO

{
    
    
    "studentClassName": "E班",
    "studentName": "林田惠"
}

转换后Student

{
    
    
    "className": "E班",
    "name": "林田惠"
}

2.2.2 集合转换

字段不相等集合相互转换时,需要定义两个Mapper,一个是单个对象的转换,另一个是集合对象转换。

转换Mapper

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
...
import java.util.List;

@Mapper(componentModel = "spring")
public interface StudentMapper {
    
    
    /**
     * 转 responseDto 字段不同
     * @param student
     * @return
     */
    @Mapping(target = "studentName",source = "name")
    @Mapping(target = "studentClassName",source = "className")
    StudentInfoResponseDTO entityToResponseList(Student student);
    /**
     * 转 responseDto list 字段不同
     * @return
     */
    List<StudentInfoResponseDTO> listEntityToResponseLists(List<Student> students);
}

转换前Student集合

[
    {
    
    
        "age": 24,
        "className": "一年级五班",
        "height": 180.0,
        "name": "我玩亚索我会C",
        "weight": 140.0
    },
    {
    
    
        "age": 25,
        "className": "铃兰五班",
        "height": 184.0,
        "name": "泷谷源治",
        "weight": 130.0
    },
    {
    
    
        "age": 26,
        "className": "铃兰一班",
        "height": 178.0,
        "name": "芹泽多摩雄",
        "weight": 160.0
    },
    {
    
    
        "age": 24,
        "className": "铃兰火箭班",
        "height": 175.0,
        "name": "辰川时生",
        "weight": 120.0
    }
]

转换后StudentInfoResponseDTO 集合

[
    {
    
    
        "studentClassName": "一年级五班",
        "studentName": "我玩亚索我会C"
    },
    {
    
    
        "studentClassName": "铃兰五班",
        "studentName": "泷谷源治"
    },
    {
    
    
        "studentClassName": "铃兰一班",
        "studentName": "芹泽多摩雄"
    },
    {
    
    
        "studentClassName": "铃兰火箭班",
        "studentName": "辰川时生"
    }
]

2.3 多个源

有些字段并不是对象中的属性,但是想赋值给转换后的对象,可以将该属性当做参数传入。

转换Mapper

import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
...
import java.util.List;

@Mapper(componentModel = "spring")
public interface StudentMapper {
    
    
    /**
     * 额外参数 转 实体类
     * @param dto
     * @param entranceTime 额外参数 入学时间
     * @return
     */
    @Mapping(target = "name",source = "dto.studentName")
    @Mapping(target = "className",source = "dto.studentClassName")
    @Mapping(target = "entranceTime",source = "entranceTime")
    Student extraParamsToEntity(StudentRequestDTO dto,String entranceTime);
}

转换前StudentRequestDTO

{
    
    
    "studentClassName": "E班",
    "studentName": "林田惠"
}

转换后Student

{
    
    
    "className": "E班",
    "entranceTime": "2022-10-18",
    "name": "林田惠"
}

注意:当mapper方法的参数有多个,手动映射时需要指定别名,如:@Mapping(target = "name",source = "dto.studentName")

2.4 默认值

想要给对象中的属性设置默认值使用defaultValue

import javax.xml.crypto.Data;
import java.time.LocalDateTime;

@Mapper(componentModel = "spring")
public interface StudentMapper {
    
    
    /**
     * 默认参数 转 实体类
     * @param dto
     * @return
     */
    @Mapping(target = "className",defaultValue = "五班")
    Student defaultToEntity(StudentRequestDTO dto);
}

2.5 数据类型映射

2.5.1 日期类型

指定日期格式。

import javax.xml.crypto.Data;
import java.time.LocalDateTime;

@Mapper(componentModel = "spring")
public interface StudentMapper {
    
    
    /**
     * 日期类型映射 转 实体类
     * @param dto
     * @param entranceTime 入学时间
     * @return
     */
    @Mapping(target = "entranceTime",dateFormat = "yyyy-MM-dd",source = "entranceTime")
    Student dateTypeToEntity(StudentRequestDTO dto,String entranceTime);
}

2.5.2 数字类型

保留两位小数。

import javax.xml.crypto.Data;
import java.time.LocalDateTime;

@Mapper(componentModel = "spring")
public interface StudentMapper {
    
    
    /**
     * 数字类型映射 转 实体类
     * @param dto
     * @param entranceTime 入学时间
     * @return
     */
    @Mapping(target = "tuition",numberFormat = "$#.00",source = "tuitionFee")
    Student dateTypeToEntity(StudentRequestDTO dto,String entranceTime);
}

2.6 表达式

entranceTime设置为当前时间
studentNo设置为随机数

@Mapper(componentModel = "spring",imports = {
    
    LocalDateTime.class, UUID.class})
public interface StudentMapper {
    
    
 /**
     * 表达式 转 实体类
     * @param dto
     * @return
     */
    @Mapping(target = "entranceTime",expression = "java(LocalDateTime.now())")
    @Mapping(target = "studentNo",expression = "java(UUID.randomUUID().toString())")
    List<Student> expressionToEntities(List<StudentRequestDTO> dto);
}

3.注意事项

在使用MapStruct时,如果有映射的字段变更,一定要先clear清除编译文件,重新install编译。

猜你喜欢

转载自blog.csdn.net/qq_42785250/article/details/127393581
今日推荐