JAVA对象相互转换的多种实现方式
方式一:MapStruct
是一个代码生成器,它基于约定优于配置的方法,极大地简化了 Java bean 类型之间的映射实现。
生成的映射代码使用普通的方法调用,因此速度快、类型安全且易于理解。
官方文档
https://mapstruct.org/documentation/installation/
更多使用示例
https://github.com/kevinLuan/mapstruct-examples
mapper-struct使用比较灵活,性能非常出色。由于它的实现是通过在开发中生成源代码的方式实现,所以对于动态对象数据拷贝并不适合。
使用示例:
// 编写User实体类和DTO实体类
@Data
public class User {
private int id;
private String nickname;
private boolean sex;
private Date registerTime;
private int status;
}
@Data
public class UserDTO {
private int id;
private String nickname;
private boolean sex;
private Date registerTime;
}
import org.mapstruct.CollectionMappingStrategy;
import org.mapstruct.Mapper;
import org.mapstruct.NullValueCheckStrategy;
import org.mapstruct.factory.Mappers;
//编写转换Mapper接口
@Mapper(collectionMappingStrategy = CollectionMappingStrategy.ADDER_PREFERRED,
nullValueCheckStrategy = NullValueCheckStrategy.ALWAYS)
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
UserDTO map(User user);
User map(UserDTO userDTO);
}
//maven工程编译项目: mvn compile
//编译插件自动生成UserMapper实现类:UserMapperImpl
import javax.annotation.Generated;
@Generated(
value = "org.mapstruct.ap.MappingProcessor",
date = "2022-04-03T15:59:10+0800",
comments = "version: 1.4.2.Final, compiler: javac, environment: Java 1.8.0_131 (Oracle Corporation)"
)
public class TestUserMapperImpl implements UserMapper {
//...
}
//介绍几个常用的注解:
@Mapping 描述转换源对象中的属性名称到目标属性名称的映射,如下
User -> UserDTO 转换示例
@Mapping(source = "users", target = "userList")
UserDTO convert(User user);
//反向转换 UserDTO -> User
@Mapping(source = "userList", target = "users")
User convert(UserDTO userDTO);
//反向转换还可以使用如下注解来完成相同的效果,当转换映射参数比较复杂的情况下,可以使用该注解简化配置
@InheritInverseConfiguration //指示方法应继承响应反向的配置
User convert(UserDTO userDTO);
//使用java表达式,来生成数据,如下示例演示,通过执行表达式中的代码动态生成数据填充到目标属性中
@Mapping(target = "uniqueId", expression = "java(CommonConverter.generateUniqueId())")
User convert(UserDTO userDTO);
//演示实现装饰器自定义映射实现
@Mapper(imports = CommonConverter.class)
//通过定义装饰器模式实现
@DecoratedWith(value = AbstractCarMapperDecorated.class)
public interface CarMapper {
CarMapper INSTANCE = Mappers.getMapper(CarMapper.class);
CarDto map(Car car);
//使用java表达式,来生成数据
@Mapping(target = "uniqueId", expression = "java(CommonConverter.generateUniqueId())")
Car map(CarDto car);
}
/**
* 实现装饰器自定义映射实现
*/
public abstract class AbstractCarMapperDecorated implements CarMapper {
private CarMapper delegate;
public AbstractCarMapperDecorated(CarMapper delegate) {
this.delegate = delegate;
}
public CarDto map(Car car) {
CarDto dto = delegate.map(car);
dto.setTitle("title:" + dto.getTitle());
return dto;
}
}
方式二:BeanCopier
BeanCopier 底层依赖cglib通过生成字节码来实现对象拷贝,性能同样非常出色。
由于使用到字节码生成方式技术,所以在动态生成字节码实现类时性能消耗比较大,不过可以通过提前预生成实现类并添加到cache中。
final static BeanCopier beanCopier = BeanCopier.create(Goods.class, GoodsDto.class, false);
//深拷贝数据
beanCopier.copy(goods, goodsDto, null);
public class Goods{
//...
}
public class GoodsDto{
//...
}
方式三:Spring BeanUtils
Spring BeanUtils实现原理是基于反射实现的数据拷贝处理,性能上相比通过字节码生成实现要慢很多。
org.springframework.beans.BeanUtils.copyProperties(source, target);
方式四:apache BeanUtils
org.apache.commons.beanutils.BeanUtils.copyProperties(do, entity);
该方法同样使用反射调用实现数据拷贝处理,性能相比Spring BeanUtils还要差一些,适合使用场景较为简单,调用频率比高的场景。
方式五:IDE idea插件:GenerateAllSetter
安装插件:using IDE plugin system
Preferences(Settings) > Plugins > Browse repositories... > find"GenerateAllSetter" > Install Plugin源码地址: https://github.com/gejun123456/intellij-generateAllSetMethod
// 编写User实体类和DTO实体类
@Data
public class User {
private int id;
private String nickname;
private boolean sex;
private Date registerTime;
private int status;
}
@Data
public class UserDTO {
private int id;
private String nickname;
private boolean sex;
private Date registerTime;
}
//然后编写转换方法
public UserDTO convertUserDTO(User user){
//TODO 将光标移到方法中空白处,使用快捷键:alt + enter(回车键) 当前使用的mac系统
//弹出:Generate setter getter converter
}
//生成后的代码如下:
public UserDTO convertUserDTO(User user){
UserDTO userDTO = new UserDTO();
userDTO.setId(user.getId());
userDTO.setNickname(user.getNickname());
userDTO.setSex(user.isSex());
userDTO.setRegisterTime(user.getRegisterTime());
return userDTO;
}
相关文章
- Java面向对象基础--类的设计及分析问题的方法---用户登录例子
- json 字符串包含数组转换为object对象是报异常java.lang.ClassCastException: net.sf.ezmorph.bean.MorphDynaBean cannot be cast to
- 关于使用JAXB读取xml文档转换为java对象报错:类的两个属性具有相同名称com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsExc...
- java中finally和return的执行顺序
- Java实现 LeetCode 441 排列硬币
- java实现 洛谷 P1017 进制转换
- Java实现第九届蓝桥杯哪天返回
- Java实现 蓝桥杯VIP 算法训练 ALGO-85进制转换
- Java实现 蓝桥杯VIP 基础练习 时间转换
- Java通过mysql-connector-java-8.0.11连接MySQL Server 8.0遇到的几个问题
- Atititjs javascript异常处理机制与java异常的转换.js exception process
- 【java】Java经典面试题整理(附答案)
- java中的transient 详细总结Java中transient关键字 对象写出流ObjectOutputStream 对象写入流ObjectInputStream
- Bean-Query 一个把对象转换为Map的Java工具库
- Java中使用Jackson,对JSON和对象进行转换
- android开发中json与java对象相互转换
- Java Web HelloWorld!
- Mindfusion.Charts and Gauges for Java
- 【java】Java 集合框架