JavaBean间的转换
⭐⭐⭐⭐⭐⭐
Github主页????https://github.com/A-BigTree
笔记链接????https://github.com/A-BigTree/Code_Learning
⭐⭐⭐⭐⭐⭐
如果可以,麻烦各位看官顺手点个star~????
文章目录
- JavaBean间的转换
- 1 Apache Commons BeanUtils
- 2 Spring的BeanUtils
- 3 Json序列化转换
- 4 MapStruct
前面文章中提到了VO、DTO、BO、PO等概念(【Java】—一篇搞懂POJO和VO、BO、DTO、PO模型),在实际工程中对于一次请求可能涉及到多个对象转换过程,如果对于每一次转换都手动去维护一个转换方法工作量是非常大的,而且在后续业务拓展时,如果我们有增加字段的需求,对于每一层的转换方法都要去维护变更,这是一件很麻烦的事情,所以下面推荐一些可以实现自动转换的方法,这里我们先定义一个用户的DTO对象和PO对象
- UserDTO:
@Data
public class UserDTO implements Serializable {
private long id;
private String userName;
private String shortName;
private int age;
}
- UserPO:
@Data
public class UserPO implements Serializable {
private long id;
private String userName;
private int age;
}
1 Apache Commons BeanUtils
Apache Commons BeanUtils 提供了 PropertyUtils.copyProperties()
和BeanUtils.copyProperties()
方法来实现对象之间属性的拷贝。
以 PropertyUtils.copyProperties()
使用方法为例:
// 方法封装
public static void copyProperties(Object dest, Object orig) {
try {
// 入参1为目标转换对象
PropertyUtils.copyProperties(dest, orig);
} catch (Exception e)
throw e;
}
特点:
PropertyUtils
支持为null
的场景;缺点:
- 它的性能问题相当差;
PropertyUtils
有自动类型转换功能,而java.util.Date
恰恰是其不支持的类型;
2 Spring的BeanUtils
对于一个Spring项目来说,这是一种常用方法,封装示例如下:
// 方法封装
public static void copyProperties(Object orig, Object dest) {
try {
// 入参2为目标转换对象
PropertyUtils.copyProperties(orig, dest);
} catch (Exception e)
throw e;
}
特点:
- 速度相对快一些;
- 第一个参数是源bean,第二个参数是目标bean,与上面的相反;
缺点:
BeanUtils
没有自动转换功能,遇到参数名相同,类型不同的参数不会进行赋值;BeanUtils
对部分属性不支持null的情况,Ineger、Boolean、Long等不支持;
3 Json序列化转换
这种方法就是将java对象转换为json,然后将JSON转换成Java对象。这里以Spring默认的序列化框架jackson
为例:
public class JsonConvertExample {
private static final ObjectMapper MAPPER = new ObjectMapper();
public static void main(String[] args) {
UserPO userPO = new UserPO();
userPO.setId(1L);
userPO.setUserName("ABigTree");
userPO.setAge(22);
String json = MAPPER.writeValueAsString(userPO);
UserDTO userDTO = MAPPER.readValue(json, UserDTO.class);
}
}
特点:
- 属性名需保持一致,或通过配置Json序列化的相关设置来满足相关需求
- 多了序列化与反序列化过程,性能大打折扣;
缺点:
- 多此一举,全是缺点????
4 MapStruct
现在要介绍一个性能爆炸、高级优雅、大厂标准的转换方法,MapStruct框架,要使用MapStruct需要先在pom.xml
中添加依赖:
<dependency>
<groupId>org.mapstruct</groupId>
<artifactId>mapstruct</artifactId>
</dependency>
如果要使用 MapStruct 库进行对象之间的映射,首先需要定义一个 Mapper 接口,并在接口中编写映射方法。然后,MapStruct 库会自动生成对应的映射实现类,接口定义如下:
import org.mapstruct.Mapper;
import org.mapstruct.Mapping;
import org.mapstruct.factory.Mappers;
@Mapper
public interface UserMapper {
UserMapper INSTANCE = Mappers.getMapper(UserMapper.class);
@Mapping(source = "shortname", target = "userName")
UserPO toUserPO(UserDTO dto);
}
除了同名字段自动转换的功能,MapStruct还支持@Mapping
等注解去配置转换过程中细节实现。
对于MapStruct为什么性能爆炸和MapStruct的进阶用法,这里先挖个坑,后面去开坑详细介绍~