MapStruct
?MapStruct官网
MapStruct
是一个代码生成器,它基于约定优于配置的方法,极大地简化了Java bean类型之间映射的实现。生成的映射代码使用简单的方法调用,因此快速、类型安全且易于理解。
在装修房屋时,一些排线尽可能的走内线
,注意会让房间显得更加整洁,美观。 MapStruct
像一位代码的装修专家,简化Java Bean的转换。
<dependency>
<groupId>org.mapstructgroupId>
<artifactId>mapstructartifactId>
<version>1.3.1.Finalversion>
dependency>
转换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"
}
转换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": "辰川时生"
}
]
当被转换的对象中的属性名称和转换的对象中的属性名称不相等时,使用注解 @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": "林田惠"
}
字段不相等集合相互转换时,需要定义两个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": "辰川时生"
}
]
有些字段并不是对象中的属性,但是想赋值给转换后的对象,可以将该属性当做参数传入。
转换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")
想要给对象中的属性设置默认值使用
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);
}
指定日期格式。
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);
}
保留两位小数。
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);
}
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);
}
在使用MapStruct
时,如果有映射的字段变更,一定要先clear
清除编译文件,重新install
编译。