一.MapStruct 介绍
1.介绍
MapStruct 是一个用于 JavaBean 之间转换的代码生成工具。它可以自动生成在两个 JavaBean 之间进行映射的代码,从而避免了手动编写重复的映射逻辑。MapStruct 支持类型转换、集合映射、嵌套映射等功能,使 JavaBean 之间的转换变得更加简单和高效。
MapStruct 提供了一种方便的方式来处理 JavaBean 之间的映射,减少了手动编写转换代码的工作量,提高了代码质量和可维护性。
2.特点与用法
以下是 MapStruct 的一些主要特点和用法:
- 零依赖:MapStruct 不依赖于任何运行时库,只需要添加 Maven 或 Gradle 依赖并进行配置即可使用。
- 类型安全:MapStruct 在编译时生成代码,因此可以在编译时捕获类型不匹配或错误映射等问题,避免运行时错误。
- 注解驱动:通过在映射方法和接口上使用注解,可以自定义映射逻辑,例如如何映射字段、如何处理集合、如何处理空值等。
- 默认映射:MapStruct 提供默认映射行为,可以自动处理名称相同且类型兼容的字段,无需手动配置。
- 嵌套映射:支持复杂对象之间的嵌套映射,可以通过配置或自定义映射方法来处理。
- 集合映射:支持集合类型的映射,可以在映射集合时自动处理元素的映射。
3.使用步骤
使用 MapStruct 的步骤:
- 在你的 Maven 或 Gradle 项目中添加 MapStruct 依赖。
- 创建源 Bean 和目标 Bean,定义它们之间的映射接口。
- 在映射接口中使用
@Mapper
注解进行标记,并在方法上使用@Mapping
等注解来指定映射细节。 - 编译项目,MapStruct 会自动生成映射实现类,无需手动编写映射逻辑。
- 在需要进行 Bean 转换的地方,调用生成的映射方法即可完成转换。
二.配置
1.pom
<properties>
<java.version>1.8</java.version>
<!-- 与1.8配置在一起,设置编码集-->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<mapstruct.version>1.4.1.Final</mapstruct.version>
</properties>
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
<version>${mapstruct.version}</version>
</dependency>
2.config
public class PageBean<T> implements Serializable {
private static final long serialVersionUID = 8656597559014685635L;
private long totalElements;
private List<T> content;
private long number;
private long size;
private long totalPages;
private long numberOfElements;
public PageBean() {
}
public PageBean(List<T> list) {
if (list != null) {
this.number = 1L;
this.size = (long) list.size();
this.totalElements = (long) list.size();
this.totalPages = 1L;
this.content = list;
this.numberOfElements = (long) list.size();
}
}
public PageBean(IPage<T> page) {
if (page != null) {
this.number = page.getCurrent();
this.size = page.getSize();
this.totalElements = page.getTotal();
this.totalPages = page.getPages();
this.content = page.getRecords();
if (this.content != null && !this.content.isEmpty()) {
this.numberOfElements = (long) this.content.size();
} else {
this.numberOfElements = 0L;
}
}
}
public List<T> getContent() {
return this.content;
}
public void setContent(List<T> content) {
this.content = content;
}
public long getSize() {
return this.size;
}
public void setSize(long size) {
this.size = size;
}
public long getTotalElements() {
return this.totalElements;
}
public void setTotalElements(long totalElements) {
this.totalElements = totalElements;
}
public long getNumber() {
return this.number;
}
public void setNumber(long number) {
this.number = number;
}
public long getTotalPages() {
return this.totalPages;
}
public void setTotalPages(long totalPages) {
this.totalPages = totalPages;
}
public long getNumberOfElements() {
return this.numberOfElements;
}
public void setNumberOfElements(long numberOfElements) {
this.numberOfElements = numberOfElements;
}
}
public interface FromConverter<T, FROM> {
T from(FROM from);
List<T> from(List<FROM> list);
default PageBean<T> from(PageBean<FROM> page) {
PageBean<T> result = new PageBean<>();
result.setTotalElements(page.getTotalElements());
result.setNumber(page.getNumber());
result.setSize(page.getSize());
result.setTotalPages(page.getTotalPages());
result.setNumberOfElements(page.getNumberOfElements());
result.setContent(this.from(page.getContent()));
return result;
}
default PageBean<T> from(IPage<FROM> page) {
PageBean<T> result = new PageBean<>();
result.setTotalElements((int) page.getTotal());
result.setNumber((int) page.getCurrent());
result.setSize((int) page.getSize());
result.setTotalPages((int) page.getPages());
result.setNumberOfElements(page.getRecords().size());
result.setContent(this.from(page.getRecords()));
return result;
}
}
public interface PropertyCopier<TARGET, T> {
void copy(@MappingTarget TARGET target, T t);
}
public interface ToConverter<T, TO> {
TO to(T t);
List<TO> to(List<T> list);
default PageBean<TO> to(PageBean<T> page) {
PageBean<TO> result = new PageBean<>();
result.setTotalElements(page.getTotalElements());
result.setNumber(page.getNumber());
result.setSize(page.getSize());
result.setTotalPages(page.getTotalPages());
result.setNumberOfElements(page.getNumberOfElements());
result.setContent(this.to(page.getContent()));
return result;
}
default PageBean<TO> to(IPage<T> page) {
PageBean<TO> result = new PageBean<>();
result.setTotalElements((int) page.getTotal());
result.setNumber((int) page.getCurrent());
result.setSize((int) page.getSize());
result.setTotalPages((int) page.getPages());
result.setNumberOfElements(page.getRecords().size());
result.setContent(this.to(page.getRecords()));
return result;
}
}
public interface TwoWayConverter<SRC, DEST> extends ToConverter<SRC, DEST>, FromConverter<SRC, DEST> {
}
三.使用
1.DTO
@Data
public class ChatbotDTO {
private Integer id;
private String question;
private String response;
private Date createTime;
private Integer isDelete;
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE)
public interface Converter extends FromConverter<ChatbotDTO, Chatbot> {
Converter INSTANCE = Mappers.getMapper(Converter.class);
}
}
2.DO
@Data
public class Chatbot extends Model<Chatbot> {
private Integer id;
private String question;
private String response;
private Date createTime;
private Integer isDelete;
}
3.调用的地方
@GetMapping("/page")
public Result selectAll(@RequestParam Integer page
, @RequestParam Integer pageSize
, @RequestParam String question) {
Page<Chatbot> pageParm = new Page<>();
pageParm.setCurrent(page);
pageParm.setSize(pageSize);
QueryWrapper<Chatbot> wrapper = new QueryWrapper<>();
wrapper.orderByDesc("id");
wrapper.eq("is_delete", 0);
if (StringUtils.isNotEmpty(question)) {
wrapper.like("question", question);
}
return Result.ok(ChatbotDTO.Converter.INSTANCE.from(this.chatbotService.page(pageParm, wrapper)));
}
四.常见问题
1.本地启动失败
-Djps.track.ap.dependencies=false