Bean 之间复制属性工具

news/2024/7/7 19:55:37

Bean 之间复制属性工具

BeanUtils

出自 Spring 的工具类, 使用也非常方便

方法定义

public static void copyProperties(Object source, Object target) throws BeansException {
    copyProperties(source, target, null, (String[]) null);
}

最常见使用方法, 第一个参数为源对象(提供内容的对象), 第二个参数为目标对象 (需要填充的对象)

BeanUtils.copyProperties(cooperativeDo, cooperativeRes);

查看源码会发现大量的使用了反射

优缺点

  • 使用非常简单方便
  • 只能 copy 属性名相同的值
  • 对于属性名不同的对象直接产生隐藏 bug, 不好排查.
  • 由于大量使用反射, 性能低

MapStruct

官网地址

比较好教程

比较火的属性复制工具, 和 Lombok 的实现原理相同. 利用编译期解析注解, 生成转换的 setter 方法.

最简单的使用方式, 定义一个 接口, 用 @Mapper 标记

@Mapper
public interface PersonMapper {
    PersonMapper INSTANCT = Mappers.getMapper(PersonMapper.class);
	
	@Mapping(target = "name", source = "personName")
	@Mapping(target = "id", ignore = true) // 忽略id,不进行映射
    PersonDTO conver(Person person);

}

在 方法上可以自定义部分映射规则

使用方式

PersonDTO dto = PersonMapper.INSTANCT.conver(person);

Person 转为 PersonDTO,

  • Personname 对应 PersonDTOpersonName
  • 忽略掉 id 属性
  • 其他属性名相同的一一对应

优缺点

  • 最终生成 setter 方法, 性能高

  • 每次都需要声明一个 接口 文件

  • 如果有 嵌套类, 属性名不一致的类, 需要大量定制

  • Debug 不方便

MapStruct Spring Extensions

官方指南

GitHub 地址

比较好的教程

MapStruct 结合 Spring framework 提供的 Converter<S,T> 接口, 可以将 生成的 转换类注入到 Ioc 容器中. 使用的时候直接 自动注入, 更方便.

最简单的使用方式

定义一个接口, 继承自 Converter, @Mapper(componentModel = "spring") 只能使用 Spring 模式

@Mapper(componentModel = "spring")
public interface CarMapper extends Converter<Car, CarDto> {

    @Mapping(target = "seats", source = "seatConfiguration")
    CarDto convert(Car car);
}

使用时直接自动注入 ConversionService , 使用所有的映射器是, 都只需要注入 ConversionService

@Autowired
private ConversionService conversionService;

Car car = ……;
CarDto carDto = conversionService.convert(car,CarDto.class);

优缺点

  • 同 MapStruct , 性能高

  • 还是需要编写接口文件

  • 统一注入 ConversionService 类型, 好记

mapstruct-spring-plus

GitHub 地址

作者博客

MapStruct Spring Extensions 的 改进型

最简单的使用方式

@Data
@AutoMap(targetType = Car.class)
public class CarDto {
    private String make;

    @AutoMapField(target = "carType")
    private String type;

}

@Data
public class Car {
    private String make;
    private String carType;
}
@Autowired
private IObjectMapper mapper;

Car entity = mapper.map(dto, Car.class);

优缺点

  • 原理同 MapStruct , 性能高
  • 不需要接口 文件
  • 统一使用 IObjectMapper 类型

BeanMappingKey

GitHub 地址

作者博客

这是个 IDEA 的插件, 直接通过插件市场搜索 BeanMappingKey 安装即可.

使用方式也很简单, 选中方法后直接右击 → BeanMappingKey

优缺点

  • 性能高
  • 方便调试
  • 不能直接生成的, 方便修改

总结

  • 对于性能要求不高, 而且两个类中大部分都是相同属性的, 推荐 BeanUtils
  • 对于使用 Spring 框架的, 有性能要求的推荐使用 MapStruct Spring Extensions 和 mapstruct-spring-plus, 因为 MapStruct Spring Extensions 是官方工具, 稳定性高, mapstruct-spring-plus 使用方便, 但是个人开源, 可能存在 bug 修复不及时
  • 对于复杂的嵌套对象, 没法直接映射的, 推荐使用 BeanMappingKey

http://lihuaxi.xjx100.cn/news/30861.html

相关文章

淘宝天猫店铺优惠券查询接口

有时&#xff0c;您需要获取店铺优惠券&#xff0c;为您的用户提供更好的优惠方案选择。 【接口功能】&#xff1a;查询商品对应的可用店铺券和商品优惠券。 【参数说明】&#xff1a; 名称类型必须描述keyString是调用key&#xff08;必须以GET方式拼接在URL中&#xff0c;…

gitee 的使用

创建分支 在谁的基础上创建 就是从谁哪里拉分支 fro&#xff1a;例如现在pycharm页面数据为dev 那个新的分支就会复制一份 dev的数据 二从gitee创建分支 1.点击分支管理--》 新建分支 会从默认分支中拉去数据 三 pull分支出现错误解决办法&#xff08;No tracked bran…

剑指offer题解(C++版)

CSDN话题挑战赛第2期 参赛话题&#xff1a;算法题解 一&#xff0c;常见数据结构 1&#xff0c;数组 3-找出数组中重复的数字4-二维数组中的查找5-替换空格29-顺时针打印矩阵leetcode 989-数组形式的整数加法leetcode26-删除有序数组中的重复项leetcode35-搜索插入位置 2&…

redis源码实践手册

文章目录为何单线程redis AE是什么redis网络模型源码为何单线程 你期望的多线程编程 VS 实际上的多线程编程 Redis v4.0&#xff08;引入多线程处理异步任务&#xff09; Redis v6.0&#xff08;正式在网络模型中实现 I/O 多线程&#xff09; redis AE是什么 Redis使用了一…

二次封装 el-table

很多中后台业务的系统中&#xff0c;表格是最高频的组件之一&#xff0c;其中一般包括搜索条件、表格展示、表格操作列、分页等。那么我们二次封装的这个表格组件就需要包含以下几个功能点&#xff1a; 1、数据自动获取和刷新 2、自定义列配置 3、分页功能 4、根据搜索条件…

【day10】LeetCode(力扣)刷题(注释详细)[707.设计链表][278.第一个错误的版本][98. 验证二叉搜索树]

CSDN话题挑战赛第2期 参赛话题&#xff1a;学习笔记 刷题打卡&#xff0c;第十天题目一、707.设计链表题目二、278.第一个错误的版本题目三、98. 验证二叉搜索树题目一、707.设计链表 原题链接&#xff1a;707.设计链表 题目描述&#xff1a; 设计链表的实现。您可以选择使用…

独立后台答题小程序源码

全新的独立后台在线答题小程序&#xff0c;不是市场上面那些微擎版本的 独立后台操作更简单内容更丰富 支持用户自定义题库 源码自带题库另外用户也可以自行添加 支持在线奖励,激励视频领取在线奖励 支持登录礼包领取 支持奖励兑换 全新音效,让用户玩得更爽 拥有排行榜,让用户互…

面向对象——继承

继承 继承是面向对象编程中非常强大的一种机制&#xff0c;它首先可以复用代码。当我们让子类从父类继承时&#xff0c;子类就获得了父类的所有功能&#xff0c;我们只需要为子类编写新增的功能。 Java使用extends关键字来实现继承 通过继承&#xff0c;子类只需要编写额外的…