本期为大家带来一个实用的对象复制工具类CopyUtil,优雅封装BeanUtils
制作CopyUtil优雅封装BeanUtils
01 场景介绍
通常情况下,一个项目会有很多的分层,比如经典的三层controller, server, mapper(dao)
在这些层之间传输数据,需要用到各种实体类,叫法不一,比如VO, DTO, ENTITY, DOMAIN等。所以,经常需要将数据从一个实体复制到另一个实体。
02 最笨的方法
最笨的方法,当然就是一个一个set,花点力气,代码量多点,但是没有性能问题,如下:
// 功能:将UserDto数据拷贝到User,userDto是已有的变量
User user = new User();
user.setId(userDTO.getId());
user.setName(userDTO.getName());
user.set...
小提示:IDEA有个插件:GenerateAllSetter,可以快速生成一堆set
盗个图了:
03 使用BeanUtils
如果嫌一个一个的set麻烦,那么可以用BeanUtils。
Spring框架内置了一个BeanUtils工具类,可以实现对象的拷贝。
-
优点:简单实用
-
缺点:用到了反射,牺牲一点点性能,不是阿里那种体量的可以忽略
基本用法如下,是不是比最笨的set简洁多了:
// 功能:将UserDto数据拷贝到User,userDto是已有的变量
User user = new User();
BeanUtils.copyProperties(userDto, user);
如果是列表的复制,则循环调用copyProperties,看起来有点麻烦!用法如下:
// 功能:将List<UserDto>数据拷贝到List<User>,userDtoList是已有的变量
List<User> userList = new ArrayList<>();
for (int i = 0, l = userDtoList.size(); i < l; i++) {
UserDto userDto = userDtoList.get(i);
User user = new User();
BeanUtils.copyProperties(userDto, user);
userList.add(user);
}
除了广为人知的copyProperties用法外,还有其它关于类方法、属性的一些操作,具体就不演示,看方法名就知道了
04 自制CopyUtil
上面的BeanUtils写法还不够简洁,特别是列表复制,所以我自制了一个CopyUtil工具类,封装了BeanUtil,用起来超级简单,如下
-
优点:更简单实用
-
缺点:用到了反射,牺牲一点点性能,不是阿里那种体量的可以忽略
源码如下:
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;
import java.util.ArrayList;
import java.util.List;
/**
* 公众号:甲蛙全栈,专注Java全栈技术分享
* @author 甲蛙
*/
public class CopyUtil {
/**
* 对象复制
*/
public static <T> T copy(Object source, Class<T> clazz) {
if (source == null) {
return null;
}
T obj = null;
try {
obj = clazz.newInstance();
} catch (Exception e) {
e.printStackTrace();
return null;
}
BeanUtils.copyProperties(source, obj);
return obj;
}
/**
* 列表复制
*/
public static <T> List<T> copyList(List source, Class<T> clazz) {
List<T> target = new ArrayList<>();
if (!CollectionUtils.isEmpty(source)){
for (Object c: source) {
T obj = copy(c, clazz);
target.add(obj);
}
}
return target;
}
}
05 使用示例
对象复制:
// 功能:将UserDto数据拷贝到User,userDto是已有的变量
// BeanUtils需要两行:
User user = new User();
BeanUtils.copyProperties(userDto, user);
// CopyUtil,只要一行:
User user = CopyUtil.copy(userDto, User.class);
列表复制:
// 功能:将List<UserDto>数据拷贝到List<User>,userDtoList是已有的变量
// BeanUtils需要好几行:
List<User> userList = new ArrayList<>();
for (int i = 0, l = userDtoList.size(); i < l; i++) {
UserDto userDto = userDtoList.get(i);
User user = new User();
BeanUtils.copyProperties(userDto, user);
userList.add(user);
}
// CopyUtil,只要一行:
List<User> userList = CopyUtil.copyList(userDtoList, User.class);
06 高频面试题
Q:你做过的项目中,有没有用过泛型,怎么使用的?
A:泛型经常用来写一些通用的类,比如工具类,上面提到的CopyUtil,或是一些数据实体类,用来存放一些不确实类型的数据。
Q:泛型和Object用法上有什么区别?
A:如果将泛型改为Object,则在使用这个工具类时,需要强制类型转换,有兴趣的可以试试。
—————— THE END ——————
微信关注:甲蛙全栈,好文不错过