MapStruct - 映射工具类
依赖
<!-- mapstruct -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>1.4.2.Final</version>
</dependency>
<!-- mapstruct-processor -->
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct-processor</artifactId>
<version>1.4.2.Final</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.24</version>
</dependency>
原理:自动生成接口实现类的class
文件
java
文件编译成class
文件时,进行了预处理,生成了接口实现类的编译文件。
使用org.mapstruct.Mapper
注解的接口,编译器自动会生成一个实现类,并实现其转换方法,最后生成实现类的class
文件。
@Mapping
(org.mapstruct.Mapper
)
@Mapping
常用于映射接口中的方法上,用于指定映射规则,指定source字段和target字段之间的映射关系
基本映射
将源对象的属性映射到目标对象的属性。
@Mapping(source = "sourceProperty", target = "targetProperty")
忽略属性
在映射过程中忽略源对象中的某些属性。
@Mapping(target = "targetProperty", ignore = true)
常量赋值
将常量值赋给目标对象的属性。
@Mapping(target = "targetProperty", constant = "constantValue")
属性格式转换
当源对象属性类型与目标对象属性类型不同时,可以指定格式转换器。
@Mapping(source = "sourceProperty", target = "targetProperty", dateFormat = "yyyy-MM-dd")
自定义映射器
使用自定义的映射器方法进行属性映射。
@Mapping(source = "sourceProperty", target = "targetProperty", qualifiedByName = "customMapper")
默认值
指定目标属性的默认值。
@Mapping(source = "sourceProperty", target = "targetProperty", defaultValue = "defaultValue")
这些用法可以单独使用,也可以组合使用,以满足复杂的映射需求。
@Mapping
注解使得MapStruct非常灵活,可以处理各种不同类型的对象映射。
用法
- 定义POJO
- 定义转换接口
- 测试
例子:StudentDO
和 StudentDTO
StudentDO
@Data
@Accessors(chain = true)
public class StudentDO implements Serializable {
private String id;
private String name;
private String gender;
private Integer age;
private String grade;
private String major;
private String description;
}
StudentDTO
@Data
@Accessors(chain = true)
public class StudentDTO implements Serializable {
private String num;
private String name;
private String gender;
private Integer age;
private String grade;
private String major;
private Object description;
private String hobbies;
private String ninumber;
}
转换接口
import org.lbb.domain.StudentDO;
import org.lbb.domain.StudentDTO;
import org.lbb.util.CustomizedConvertUtil;
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
/**
* @Auther: Ban
* @Date: 2024/4/11 09:40
* @Description: StudentDO 和 StudentDTO的转换
*/
@Mapper(uses = CustomizedConvertUtil.class)
public interface StudentMapStruct {
StudentMapStruct INSTANCE = Mappers.getMapper(StudentMapStruct.class);
// 基本映射
@Mapping(source = "id", target = "num")
// 自定义映射器
@Mapping(source = "description", target = "description", qualifiedByName = "jsonToObject")
StudentDTO toStudentDTO(StudentDO student);
}
自定义映射器
public class **CustomizedConvertUtil** {
@Named("jsonToObject")
public Object jsonToObject(String jsonStr) {
if (StringUtils.isBlank(jsonStr)) {
return null;
}
return JSONObject.parseObject(jsonStr, Object.class);
}
}
转换测试
@Slf4j
@SpringBootTest
public class StudentMapStructTest {
private StudentDO student;
@BeforeEach
void init() {
student = new StudentDO()
.setId("1")
.setName("张三")
.setGender("男")
.setAge(18)
.setGrade("2024")
.setMajor("计算机科学与技术")
.setDescription("{\"id\":1,\"name\":\"测试1\"}");
}
@Test
void mapStructTest() {
log.info("student: {}", student);
// 使用:转换
StudentDTO studentDTO = StudentMapStruct.INSTANCE.toStudentDTO(student);
log.info("studentDTO: {}", studentDTO);
assertNotNull(studentDTO);
}
}
日志打印
2024-04-11 15:10:07.697 INFO 292 --- [main] student: StudentDO(id=1, name=张三, gender=男, age=18, grade=2024, major=计算机科学与技术, description={"id":1,"name":"测试1"}, createDt=null, updateDt=null)
2024-04-11 15:10:07.714 INFO 292 --- [main] studentDTO: StudentDTO(num=1, name=张三, gender=男, age=18, grade=2024, major=计算机科学与技术, hobbies=null, ninumber=null, description={"name":"测试1","id":1}, createDt=null, updateDt=null)