当前位置: 首页 > news >正文

mapstruct 无法生成字段映射code

文章目录

  • 前言-随便写点
  • 一、maven
  • 二、搞个基类
    • 1. BaseMapping
    • 2. ExtendMapping
    • 3. 使用示例
  • 三、没有生成字段映射?
  • 总结

前言-随便写点

MapStruct 是一个 Java 注释处理器,用于生成类型安全的 bean 映射类。
您所要做的就是定义一个映射器接口,该接口可以声明任何您所需的映射方法。在编译期间,MapStruct 将生成此接口的实现。这个实现使用普通的 Java 方法调用(get,set方法)来映射源对象和目标对象,而不是使用反射。
项目编译后generated-sources\annotations路径下会找到编译后的文件,这里会对两个对象的属性一一set

一、maven

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mapstruct</groupId>
            <artifactId>mapstruct-processor</artifactId>
        </dependency>

二、搞个基类

1. BaseMapping

import org.mapstruct.*;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * MapStruct映射基类,直接继承接口即可使用通用方法,针对性指定需在继承类的接口方法上指定
 * <p>
 * 例: public interface xxxMapping extends BaseMapping<xxxDO, xxxDTO>
 * <p>
 * 具体用法可参考单元测试,建议配合MapStruct Support插件使用
 */
@MapperConfig(componentModel = "spring")
public interface BaseMapping<F, T> {

    /**
     * 正向映射
     */
    @InheritConfiguration
    T convertTo(F obj);

    /**
     * 反向映射
     */
    @InheritInverseConfiguration(name = "convertTo")
    F convertFrom(T obj);

    @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
    void supplementFrom(T t, @MappingTarget F f);

    /**
     * 正向映射(List)
     */
    default List<T> convertTo(List<F> list) {
        if (list == null) {
            return null;
        }

        List<T> result = new ArrayList<T>(list.size());
        for (F f : list) {
            if (f == null) {
                continue;
            }
            result.add(convertTo(f));
        }

        return result;
    }

    /**
     * 反向映射(List)
     */
    default List<F> convertFrom(List<T> list) {
        if (list == null) {
            return null;
        }

        List<F> result = new ArrayList<F>(list.size());
        for (T t : list) {
            if (t == null) {
                continue;
            }
            result.add(convertFrom(t));
        }

        return result;
    }

    /**
     * 正向映射的后置处理,List映射会自动继承此配置
     */
    @AfterMapping
    default void handleAfterConvertTo(F src, @MappingTarget T dest) {
        afterConvertTo(src, dest);
    }

    /**
     * 反向映射的后置处理,List映射会自动继承此配置
     */
    @AfterMapping
    default void handleAfterConvertFrom(T src, @MappingTarget F dest) {
        afterConvertFrom(src, dest);
    }

    /**
     * 正向映射的后置处理,List映射会自动继承此配置
     */
    default void afterConvertTo(F src, T dest) {
        //TODO 覆盖此方法处理其他复杂转换逻辑
    }

    /**
     * 反向映射的后置处理,List映射会自动继承此配置
     */
    default void afterConvertFrom(T src, F dest) {
        //TODO 覆盖此方法处理其他复杂转换逻辑
    }

}

2. ExtendMapping

import org.mapstruct.*;

import java.util.ArrayList;
import java.util.List;

/**
 * <p>
 * MapStruct映射基类,直接继承接口即可使用通用方法,针对性指定需在继承类的接口方法上指定
 * <p>
 * 例: public interface xxxMapping extends BaseMapping<PO, Req, Resp>
 * <p>
 *
 */
@MapperConfig(componentModel = "spring")
public interface ExtendMapping<PO, Req, Resp> {

    Resp po2Resp(PO obj);

    PO req2PO(Req obj);

    @BeanMapping(nullValuePropertyMappingStrategy = NullValuePropertyMappingStrategy.IGNORE)
    void supplementPO(Req req, @MappingTarget PO PO);

    default List<Resp> po2Resp(List<PO> list) {
        if (list == null) {
            return null;
        }

        List<Resp> result = new ArrayList<>(list.size());
        for (PO PO : list) {
            if (PO == null) {
                continue;
            }
            result.add(po2Resp(PO));
        }

        return result;
    }

    default List<PO> req2PO(List<Req> list) {
        if (list == null) {
            return null;
        }

        List<PO> result = new ArrayList<>(list.size());
        for (Req req : list) {
            if (req == null) {
                continue;
            }
            result.add(req2PO(req));
        }

        return result;
    }

    /**
     * 转换Resp的前置处理
     */
    @BeforeMapping
    default void handleBeforePo2Resp(PO src, @MappingTarget Resp target) {
        before2Resp(src, target);
    }

    /**
     * 转换Resp的后置处理
     */
    @AfterMapping
    default void handleAfterPo2Resp(PO src, @MappingTarget Resp target) {
        after2Resp(src, target);
    }

    /**
     * 转换PO的前置处理
     */
    @BeforeMapping
    default void handleBeforeReq2PO(Req src, @MappingTarget PO target) {
        before2PO(src, target);
    }

    /**
     * 转换PO的后置处理
     */
    @AfterMapping
    default void handleAfterReq2PO(Req src, @MappingTarget PO target) {
        after2PO(src, target);
    }

    default void before2Resp(PO src, Resp target) {
        //TODO 覆盖此方法处理其他复杂转换逻辑
    }

    default void before2PO(Req src, PO dest) {
        //TODO 覆盖此方法处理其他复杂转换逻辑
    }

    default void after2Resp(PO src, Resp target) {
        //TODO 覆盖此方法处理其他复杂转换逻辑
    }

    default void after2PO(Req src, PO dest) {
        //TODO 覆盖此方法处理其他复杂转换逻辑
    }

}

3. 使用示例

@Mapper(componentModel = "spring")
public interface BisMenuMapping extends ExtendMapping<BisMenuPO, BisMenuReq, BisMenuResp> {

}

三、没有生成字段映射?

查看target\generated-sources\annotations下生成的类,发现只创建了一个空对象,没有生成任何set代码。
这里用到了lombok
排查发现,maven引用的时候先引用的mapstruct后lombok,导致mapstruct构建set code的时候,对象的get set方法还没有被lombok生成,导致此问题。
解决办法:
先引用lombok,后mapstruct 或者maven plugin 指定编译顺序。

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <annotationProcessorPaths>
                        <path>
                            <groupId>org.projectlombok</groupId>
                            <artifactId>lombok</artifactId>
                            <version>${lombok.version}</version>
                        </path>
                        <path>
                            <groupId>org.mapstruct</groupId>
                            <artifactId>mapstruct-processor</artifactId>
                            <version>${org.mapstruct.version}</version>
                        </path>
                    </annotationProcessorPaths>
                </configuration>
            </plugin>
        </plugins>
    </build>

总结

在lombok和mapstruct同时使用时,一定要注意将编译顺序指定一下,不然mapstruct无法生成实现类无法使用。

相关文章:

  • 全志V853常用模型跑分数据
  • 迅为3A5000开发板龙芯自主指令集从里到外100%全国产设计方案
  • 安卓面经<15/30>之SharedPreference解析
  • LeetCode 10. 正则表达式匹配(C++)*
  • 《计算机体系结构量化研究方法》第2章-存储器层次结构设计 2.1 引言
  • android 9.0 屏蔽所有电话来电功能
  • 代替塞规的高精度孔径测量方法——泊肃叶压差法
  • Vue的父传子
  • JMH - Java微基准测试工具套件
  • 【矩阵论】7. 范数理论——非负/正矩阵
  • 算法day56|583,72
  • 前端工程化与 webpack:webpack 的基本使用
  • 新能源电池进入高速发展阶段,数商云S2B2C商城赋能企业分销渠道管理更便捷
  • 2步就能实现给视频去色并裁剪画面
  • 电信运营商网络流量采集模型研究及应用
  • 知识图谱库汇总!——教育领域能够直接应用的知识图谱
  • OpenCV inRange 函数使用详解
  • 倒角算法推导
  • 支持docker部署的开源网盘汇总
  • python index() 与 rindex() 方法的使用