SpringBoot3集成MapstructPlus

Mapstruct Plus 是 Mapstruct 的增强工具,在 Mapstruct 的基础上,实现了自动生成 Mapper 接口的功能,并强化了部分功能,使 Java 类型转换更加便捷、优雅。

Mapstruct Plus 是 Mapstruct 的增强工具,在 Mapstruct 的基础上,实现了自动生成 Mapper 接口的功能,并强化了部分功能,使 Java 类型转换更加便捷、优雅。

引入依赖

根pom.xml

<properties>
    <java.version>21</java.version>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <!-- 插件版本 -->
    <maven-compiler-plugin.version>3.11.0</maven-compiler-plugin.version>
    <lombok.version>1.18.38</lombok.version>
	<mapstruct-plus.version>1.4.8</mapstruct-plus.version>
    <lombok-mapstruct-binding.version>0.2.0</lombok-mapstruct-binding.version>
</properties>

<dependencyManagement>
  <dependencies>
      <!-- MapStructPlus 依赖
           https://mvnrepository.com/artifact/io.github.linpeilie/mapstruct-plus-spring-boot-starter
      -->
      <dependency>
          <groupId>io.github.linpeilie</groupId>
          <artifactId>mapstruct-plus-spring-boot-starter</artifactId>
          <version>${mapstruct-plus.version}</version>
      </dependency>
      
    </dependencies>
</dependencyManagement>

<build>
    <plugins>
        <!-- Maven 编译插件 -->
        <plugin>
            <groupId>org.apache.maven.plugins</groupId>
            <artifactId>maven-compiler-plugin</artifactId>
            <version>${maven-compiler-plugin.version}</version>
            <configuration>
                <source>${java.version}</source>    <!-- 源代码使用的JDK版本 -->
                <target>${java.version}</target>    <!-- 需要生成的目标class文件的编译版本 -->
                <encoding>${project.build.sourceEncoding}</encoding> <!-- 字符集编码,防止中文乱码 -->
                <compilerArgs>
                    <arg>-parameters</arg>  <!-- 保留方法参数名称 -->
                </compilerArgs>

                <annotationProcessorPaths>
                    <path>
                        <groupId>io.github.linpeilie</groupId>
                        <artifactId>mapstruct-plus-processor</artifactId> <!-- 定义了一个注解处理器的依赖项, 必须手动配置到此处,才能在编译阶段生成具体的映射实现类,避免运行时的性能开销 -->
                        <version>${mapstruct-plus.version}</version>
                    </path>
                    <!-- 依赖地址:https://mvnrepository.com/artifact/org.projectlombok/lombok-mapstruct-binding
                             解决 Lombok 与 MapStruct 的编译顺序冲突
                             强制 Lombok 在 MapStruct 处理完映射代码后再运行,从而避免字段缺失或无法识别的问题
                             官网提示:https://mapstruct.org/documentation/stable/reference/html/#lombok
                        -->
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok-mapstruct-binding</artifactId>
                        <version>${lombok-mapstruct-binding.version}</version>
                    </path>
                    <!--
                        一旦你使用了 <annotationProcessorPaths>,Maven 将只使用你指定的处理器,默认的 Lombok 注解处理器不会自动加入。
                        所以此处需显式添加 Lombok 注解处理器 依赖
                        -->
                    <path>
                        <groupId>org.projectlombok</groupId>
                        <artifactId>lombok</artifactId>
                        <version>${lombok.version}</version>
                    </path>
                </annotationProcessorPaths>
            </configuration>
        </plugin>
    </plugins>
</build>

封装工具类

公共模块pom.xml

<dependencies>
	<!-- 包含:SpringUtils -->
    <dependency>
        <groupId>cn.hutool</groupId>
        <artifactId>hutool-extra</artifactId>
    </dependency>
    <!-- mapstruct-plus映射工具类 -->
    <dependency>
        <groupId>io.github.linpeilie</groupId>
        <artifactId>mapstruct-plus-spring-boot-starter</artifactId>
    </dependency>
</dependencies>

工具类MapstructUtils.java

package com.zibocoder.plugins.common.util;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import io.github.linpeilie.Converter;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import java.util.List;
import java.util.Map;

/**
 * @author zibocoder
 * @date 2025/7/19 17:34:58
 * @description Mapstruct工具类
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE) // 自动生成一个私有的无参构造方法(禁止实例化:构造函数是私有的,意味着这个类 不能从外部被实例化)
public class MapstructUtils {
    private final static Converter CONVERTER = SpringUtil.getBean(Converter.class);

    /**
     * 将 T 类型对象,转换为 desc 类型的对象并返回
     *
     * @param source 数据来源实体
     * @param desc   描述对象 转换后的对象
     * @return desc
     */
    public static <T, V> V convert(T source, Class<V> desc) {
        if (ObjectUtil.isNull(source)) {
            return null;
        }
        if (ObjectUtil.isNull(desc)) {
            return null;
        }
        return CONVERTER.convert(source, desc);
    }

    /**
     * 将 T 类型对象,按照配置的映射字段规则,给 desc 类型的对象赋值并返回 desc 对象
     *
     * @param source 数据来源实体
     * @param desc   转换后的对象
     * @return desc
     */
    public static <T, V> V convert(T source, V desc) {
        if (ObjectUtil.isNull(source)) {
            return null;
        }
        if (ObjectUtil.isNull(desc)) {
            return null;
        }
        return CONVERTER.convert(source, desc);
    }

    /**
     * 将 T 类型的集合,转换为 desc 类型的集合并返回
     *
     * @param sourceList 数据来源实体列表
     * @param desc       描述对象 转换后的对象
     * @return desc
     */
    public static <T, V> List<V> convert(List<T> sourceList, Class<V> desc) {
        if (ObjectUtil.isNull(sourceList)) {
            return null;
        }
        if (CollUtil.isEmpty(sourceList)) {
            return CollUtil.newArrayList();
        }
        return CONVERTER.convert(sourceList, desc);
    }

    /**
     * 将 Map 转换为 beanClass 类型的集合并返回
     *
     * @param map       数据来源
     * @param beanClass bean类
     * @return bean对象
     */
    public static <T> T convert(Map<String, Object> map, Class<T> beanClass) {
        if (MapUtil.isEmpty(map)) {
            return null;
        }
        if (ObjectUtil.isNull(beanClass)) {
            return null;
        }
        return CONVERTER.convert(map, beanClass);
    }
}

实际应用

DeptAddForm->DeptEntity DeptAddForm.java

package com.zibocoder.system.domain.form;

import com.zibocoder.system.domain.entity.DeptEntity;
import io.github.linpeilie.annotations.AutoMapper;
import jakarta.validation.constraints.NotBlank;
import jakarta.validation.constraints.NotNull;
import lombok.Data;
import org.hibernate.validator.constraints.Length;

/**
 * @author zibocoder
 * @date 2025/7/13 06:54:08
 * @description 部门添加表单
 */
@Data
@AutoMapper(target = DeptEntity.class, reverseConvertGenerate = false) //自动映射当前类与 DeptEntity.class 之间的字段对应关系,reverseConvertGenerate = false 表示不生成反向转换方法。
public class DeptAddForm {
    /**
     * 部门名称
     */
    @NotBlank(message = "部门名称不能为空")
    @Length(min = 1, max = 30, message = "部门名称长度不能超过{max}个字符")
    private String deptName;
    /**
     * 父部门ID
     */
    @NotNull(message = "父部门ID不能为空")
    private Long parentId;
    /**
     * 排序
     */
    @NotNull(message = "显示顺序不能为空")
    private Integer theSort;
    /**
     * 备注
     */
    private String remark;
}

DeptEntity.java

package com.zibocoder.system.domain.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

/**
 * @author zibocoder
 * @date 2025/7/10 08:16:20
 * @description 部门实体对象
 */
@Data
@TableName(value = "sys_dept", autoResultMap = true)
public class DeptEntity {
    /**
     * 部门ID
     */
    @TableId(type = IdType.AUTO)
    private Long deptId;
    /**
     * 部门名称
     */
    private String deptName;
    /**
     * 父部门ID
     */
    private Long parentId;
    /**
     * 祖级列表
     */
    private String ancestors;
    /**
     * 排序
     */
    private String theSort;
    /**
     * 部门状态:是否被禁用 false-0否 true-1是
     */
    private Boolean disabledFlag;
    /**
     * 备注
     */
    private String remark;
}

业务类 DeptService.java

/**
 * 新增部门
 * @param deptAddForm 部门新增表单
 * @return 响应结果
 */
public ResponseResult<Void> addDept(DeptAddForm deptAddForm) {
    ...
    DeptEntity deptEntity = MapstructUtils.convert(deptAddForm, DeptEntity.class);
    ...
    deptMapper.insert(deptEntity);
    return ResponseResult.ok();
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值