mapstruct常用属性填充示例

本文介绍如何使用MapStruct简化Java对象之间的映射过程。通过示例演示了依赖引入、自定义Mapper接口的方法定义及其实现原理。适用于JDK8及以上版本。

适用版本jdk8、jdk11

第一步 引入坐标


<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct</artifactId>
    <version>1.4.1.Final</version>
</dependency>
<dependency>
    <groupId>org.mapstruct</groupId>
    <artifactId>mapstruct-processor</artifactId>
    <version>1.4.1.Final</version>
    <scope>provided</scope>
</dependency>

第二步 定义mapper

@Mapper
public interface GoodInfoMapper {
 
    GoodInfoMapper INSTANCE = Mappers.getMapper(GoodInfoMapper.class);
 
    /**
     * GoodInfoDTO的属性和GoodInfoVO属性相同时不需要显示指定@Mapping
     * @param good
     * @return
     */
    GoodInfoVO toGoodInfoVO(GoodInfoDTO good);
 
    /**
     *
     * 此方法必须写 {@link GoodInfoMapper#toGoodInfoVO}方法 原因查看编译后class文件
     * @param goods
     * @return
     */
    List<GoodInfoVO> toGoodInfoVOs(List<GoodInfoDTO> goods);
 
    @Mappings({
            @Mapping(source = "typeName",target = "typeName"),
            @Mapping(source = "good.goodId",target = "goodId"),
            @Mapping(source = "good.goodName",target = "goodName"),
            @Mapping(source = "good.goodPrice",target = "goodPrice")
    })
    GoodInfoVO toGoodInfoVO(GoodInfoDTO good, String typeName);
 
 
    @Mappings({
            @Mapping(target = "remainTime", expression = "java(mapRemainTime(goodInfoFrom.getDateTime()))")
    })
    GoodInfoVO toGoodInfoVO(GoodInfoFrom goodInfoFrom);
 
    /**
     * mapRemainTime.
     * @param endTime Date
     * @return long
     */
    default long mapRemainTime(Date endTime) {
        if (endTime != null) {
            return endTime.getTime() - System.currentTimeMillis();
        }
        return 0L;
    }
 
 
    @Mapping(target = "goodId", expression = "java(goodInfoFrom.getGoodId() != null ? goodInfoFrom.getGoodId() : \"0\")")
    GoodInfoVO nonNullGoodIdToGoodInfoVO(GoodInfoFrom goodInfoFrom);
 
}

第三步 使用

@RestController
public class GoodInfoController {
 
    /**
     * 查询商品详情
     * @param id
     * @return
     */
    @RequestMapping(value = "/detail/{id}")
    public GoodInfoVO detail(@PathVariable("id") Long id)
    {
 
        GoodInfoDTO goodInfoBean = new GoodInfoDTO();
        goodInfoBean.setGoodId("232").setGoodName("冰箱").setGoodPrice(23.1d).setTypeName("厨房家电");
 
        //返回转换dto
        GoodInfoFrom goodInfoFrom  = new GoodInfoFrom();
        goodInfoFrom.setGoodId("fsfewgfdasd");
        GoodInfoVO goodInfoVO = GoodInfoMapper.INSTANCE.nonNullGoodIdToGoodInfoVO(goodInfoFrom);
 
        return goodInfoVO;
    }
 
}

第四步 运行maven compile 及查看编译后target下XXMapperImpl.class文件

public class GoodInfoMapperImpl implements GoodInfoMapper {
    public GoodInfoMapperImpl() {
    }
 
    public GoodInfoVO toGoodInfoVO(GoodInfoDTO good) {
        if (good == null) {
            return null;
        } else {
            GoodInfoVO goodInfoVO = new GoodInfoVO();
            goodInfoVO.setGoodId(good.getGoodId());
            goodInfoVO.setGoodName(good.getGoodName());
            goodInfoVO.setGoodPrice(good.getGoodPrice());
            goodInfoVO.setTypeName(good.getTypeName());
            return goodInfoVO;
        }
    }
 
    public List<GoodInfoVO> toGoodInfoVOs(List<GoodInfoDTO> goods) {
        if (goods == null) {
            return null;
        } else {
            List<GoodInfoVO> list = new ArrayList(goods.size());
            Iterator var3 = goods.iterator();
 
            while(var3.hasNext()) {
                GoodInfoDTO goodInfoDTO = (GoodInfoDTO)var3.next();
                list.add(this.toGoodInfoVO(goodInfoDTO));
            }
 
            return list;
        }
    }
 
    public GoodInfoVO toGoodInfoVO(GoodInfoDTO good, String typeName) {
        if (good == null && typeName == null) {
            return null;
        } else {
            GoodInfoVO goodInfoVO = new GoodInfoVO();
            if (good != null) {
                goodInfoVO.setGoodId(good.getGoodId());
                goodInfoVO.setGoodName(good.getGoodName());
                goodInfoVO.setGoodPrice(good.getGoodPrice());
            }
 
            if (typeName != null) {
                goodInfoVO.setTypeName(typeName);
            }
 
            return goodInfoVO;
        }
    }
 
    public GoodInfoVO toGoodInfoVO(GoodInfoFrom goodInfoFrom) {
        if (goodInfoFrom == null) {
            return null;
        } else {
            GoodInfoVO goodInfoVO = new GoodInfoVO();
            goodInfoVO.setGoodId(goodInfoFrom.getGoodId());
            goodInfoVO.setGoodName(goodInfoFrom.getGoodName());
            goodInfoVO.setGoodPrice(goodInfoFrom.getGoodPrice());
            goodInfoVO.setTypeName(goodInfoFrom.getTypeName());
            goodInfoVO.setRemainTime(this.mapRemainTime(goodInfoFrom.getDateTime()));
            return goodInfoVO;
        }
    }
 
    public GoodInfoVO nonNullGoodIdToGoodInfoVO(GoodInfoFrom goodInfoFrom) {
        if (goodInfoFrom == null) {
            return null;
        } else {
            GoodInfoVO goodInfoVO = new GoodInfoVO();
            goodInfoVO.setGoodName(goodInfoFrom.getGoodName());
            goodInfoVO.setGoodPrice(goodInfoFrom.getGoodPrice());
            goodInfoVO.setTypeName(goodInfoFrom.getTypeName());
            goodInfoVO.setGoodId(goodInfoFrom.getGoodId() != null ? goodInfoFrom.getGoodId() : "0");
            return goodInfoVO;
        }
    }
}

示例一:直接植入代码片段

@Mappings({
        @Mapping(target = "cellPhone", expression = "java(handle(rStoreFansRecordDO.getMaskPhone()))"),
        //接口只能有一个默认方法,其他简单转换需求可直接植入代码片段
        @Mapping(target = "plainCellPhone", expression = "java(rStoreFansRecordDO.getCellPhone() == null?\"\":rStoreFansRecordDO.getCellPhone())")
})
CustomerPageResponseDTO toCustomerPageResponseDTO(RStoreFansRecordDO rStoreFansRecordDO);

点击maven插件 complie命令 查看结果

 

示例二:类型不匹配时可配置忽略该字段自动转换,另外在代码中自定义转化

@Mappings({
        @Mapping(target = "signintime", ignore = true),
        @Mapping(target = "signouttime", ignore = true)
})
GuideWorkTargetResDTO toGuideWorkTargetResDTO(OrgWorkOrderDistribution orgWorkOrderDistribution);
### Java 常用工具类、库及其使用场景 Java 作为一种广泛应用的编程语言,拥有丰富的工具类和库来提升开发效率。这些工具类通常封装了常见的操作逻辑,避免开发者重复造轮子,同时确保代码的健壮性和可维护性。 #### Spring Framework 的 `org.springframework.util` 包 Spring 提供的工具类广泛用于企业级应用开发,其中 `CollectionUtils` 是一个非常实用的类,用于处理集合相关的操作。例如: - `CollectionUtils.isEmpty()`:判断集合是否为空。 - `CollectionUtils.containsAny()`:检查两个集合是否有交集。 这些方法简化了集合的操作,适用于数据过滤、权限控制等业务逻辑[^1]。 #### Apache Commons Collections 的 `org.apache.commons.collections.CollectionUtils` Apache Commons 提供了一套通用的工具类,`CollectionUtils` 在功能上与 Spring 的实现类似,但其适用范围更广,特别是在非 Spring 环境中。它支持的操作包括: - `CollectionUtils.subtract()`:从一个集合中移除另一个集合中的元素。 - `CollectionUtils.union()`:获取两个集合的并集。 这类操作在处理复杂的数据结构时非常有用,例如数据分析或报表生成场景。 #### 对象拷贝工具类 对象拷贝是 Java 开发中常见的需求,尤其是在实体类之间的属性赋值。`BeanUtils.copyProperties()` 是 Spring 提供的一个高效工具类,能够自动将一个对象的属性值复制到另一个对象中。例如: ```java Cat cat = new Cat(); cat.setName("tom"); cat.setAge(5); Dog dog = new Dog(); BeanUtils.copyProperties(dog, cat); ``` 这种方式避免了手动编写大量 `setter` 和 `getter` 方法调用代码,适用于需要频繁进行对象转换的场景,如数据传输对象(DTO)与实体类之间的映射[^2]。 #### 其他常用工具类 除了上述提到的工具类外,以下是一些其他常用Java 工具类及其典型应用场景: ##### `StringUtils`(Spring 或 Apache Commons Lang) - **用途**:处理字符串操作,如判断字符串是否为空、截取、拼接等。 - **使用场景**:表单验证、日志处理等涉及字符串操作的场景。 - 示例方法: - `StringUtils.hasText()`:判断字符串是否包含非空白字符。 - `StringUtils.split()`:按指定分隔符分割字符串。 ##### `FileUtils`(Apache Commons IO) - **用途**:文件读写、目录遍历等操作。 - **使用场景**:文件上传下载、日志文件分析等。 - 示例方法: - `FileUtils.readFileToString()`:将文件内容读取为字符串。 - `FileUtils.writeLines()`:将集合内容写入文件。 ##### `DateUtils`(Apache Commons Lang) - **用途**:日期时间的加减、格式化等操作。 - **使用场景**:处理时间戳、计算时间差等。 - 示例方法: - `DateUtils.addDays()`:对日期增加指定天数。 - `DateUtils.truncate()`:截断日期时间到指定精度。 ##### `Optional`(Java 8+ 标准库) - **用途**:解决空指针异常问题,提供一种优雅的方式来处理可能为 null 的值。 - **使用场景**:返回可能为空的结果时,如数据库查询、API 调用结果处理。 - 示例方法: - `Optional.ofNullable()`:创建一个可能为空的 Optional 实例。 - `Optional.orElse()`:如果值不存在,则返回默认值。 ##### `Objects`(Java 标准库) - **用途**:提供了一些用于对象比较、哈希码生成等方法。 - **使用场景**:对象比较、哈希计算等。 - 示例方法: - `Objects.equals()`:安全地比较两个对象是否相等。 - `Objects.hash()`:生成对象的哈希码。 ##### `Arrays`(Java 标准库) - **用途**:数组操作,如排序、搜索、填充等。 - **使用场景**:处理原始数据类型数组或对象数组。 - 示例方法: - `Arrays.sort()`:对数组进行排序。 - `Arrays.binarySearch()`:在已排序数组中查找特定元素。 ##### `Collections`(Java 标准库) - **用途**:提供静态方法用于操作集合,如排序、反转、洗牌等。 - **使用场景**:集合数据处理。 - 示例方法: - `Collections.sort()`:对列表进行排序。 - `Collections.shuffle()`:随机打乱列表顺序。 #### 第三方库推荐 除了标准库和 Apache Commons、Spring 提供的工具类外,还可以考虑以下第三方库以增强开发效率: ##### Guava(Google Core Libraries) Guava 提供了许多高级功能,如不可变集合、缓存、函数式编程支持等。 - **使用场景**:需要高性能缓存、不可变集合或函数式编程特性时。 - 示例类: - `ImmutableList`:不可变列表。 - `CacheBuilder`:构建本地缓存。 ##### Lombok Lombok 通过注解自动生成代码,减少样板代码的编写。 - **使用场景**:简化实体类的 `getter`、`setter`、`toString()` 等方法的编写。 - 示例注解: - `@Data`:自动生成 `getter`、`setter`、`equals`、`hashCode` 等方法。 - `@NoArgsConstructor`:生成无参构造函数。 ##### MapStruct MapStruct 是一个基于注解处理器的 Java Bean 映射工具,能够在编译时生成高效的映射代码。 - **使用场景**:替代 `BeanUtils.copyProperties()`,提供类型安全且性能更高的对象拷贝方式。 - 示例接口: ```java @Mapper public interface CarMapper { CarMapper INSTANCE = Mappers.getMapper(CarMapper.class); CarDto carToCarDto(Car car); } ```
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值