自制CopyUtil优雅封装BeanUtils

本期为大家带来一个实用的对象复制工具类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  ——————

微信关注:甲蛙全栈,好文不错过

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值