江门电商网站设计培训,wordpress mp3播放器,广州手表网站,国外网页设计欣赏1. 原始转换
提起对象转换#xff0c;每个程序员都不陌生#xff0c;比如项目中经常涉及到的DO、DTO、VO之间的转换#xff0c;举个例子#xff0c;假设现在有个OrderDTO#xff0c;定义如下所示#xff1a;
public class OrderDTO {private long id;private Long user…1. 原始转换
提起对象转换每个程序员都不陌生比如项目中经常涉及到的DO、DTO、VO之间的转换举个例子假设现在有个OrderDTO定义如下所示
public class OrderDTO {private long id;private Long userId;private String orderNo;private Date gmtCreated;// 省略get、set方法
}有个OrderVO定义如下所示
public class OrderVO {private long id;private long userId;private String orderNo;private Date gmtCreated;// 省略get、set方法
}如果不使用任何转换工具代码是下面这样的
public static void main(String[] args) {OrderDTO orderDTO new OrderDTO();orderDTO.setId(1L);orderDTO.setUserId(123L);orderDTO.setOrderNo(20210518000001);orderDTO.setGmtCreated(new Date());OrderVO orderVO new OrderVO();orderVO.setId(orderDTO.getId());orderVO.setUserId(orderDTO.getUserId());orderVO.setOrderNo(orderDTO.getOrderNo());orderVO.setGmtCreated(orderDTO.getGmtCreated());System.out.println(orderVO.getId());System.out.println(orderVO.getUserId());System.out.println(orderVO.getOrderNo());System.out.println(orderVO.getGmtCreated());
}运行结果 2. 使用BeanUtils.copyProperties转换
因为项目中类似上面的转换多而繁琐所以很多公司的项目中会使用Spring框架里的BeanUtils.copyProperties来做对象转换代码如下所示
OrderVO orderVO new OrderVO();
BeanUtils.copyProperties(orderDTO, orderVO);一行代码搞定很方便运行结果也和原来一模一样。
不过这个工具带来便利的同时也带来了很多问题稍微不注意就会踩坑接下来就总结下使用这个工具常见的几个坑。
3. 踩坑经历
3.1 包装类型转基本类型问题 java.lang.IllegalArgumentException 细心的你可能会发现OrderDTO中的userId字段我定义的是Long类型 而OrderVO中的userId字段我定义的是long类型 然后我们运行下下面所示的代码
public static void main(String[] args) {OrderDTO orderDTO new OrderDTO();orderDTO.setId(1L);orderDTO.setUserId(null);orderDTO.setOrderNo(20210518000001);orderDTO.setGmtCreated(new Date());OrderVO orderVO new OrderVO();BeanUtils.copyProperties(orderDTO, orderVO);
}会看到代码抛了java.lang.IllegalArgumentException异常 3.2 空格问题
假设OrderVO的orderNo字段是用户自定义的用户不小心输入了空格使用BeanUtils.copyProperties后空格会带入到OrderDTO的orderNo字段如果不小心就会把脏数据落到数据库而我们希望的是去除空格再落库的造成一系列后续问题
public static void main(String[] args) {OrderVO orderVO new OrderVO();orderVO.setId(1L);orderVO.setUserId(123L);// 模拟空格场景orderVO.setOrderNo( 20210518000001 );orderVO.setGmtCreated(new Date());OrderDTO orderDTO new OrderDTO();BeanUtils.copyProperties(orderVO, orderDTO);System.out.println(orderDTO.getOrderNo());
}运行结果 3.3 查找不到字段引用
使用BeanUtils.copyProperties后会看到字段并没有引用其实是有用到的如下图所示 有些小伙伴在看代码时看到字段没有地方引用可能就忍不住想删掉结果就导致真正使用该字段的地方取不到值产生bug。
3.4 前端误传字段直接把数据库覆盖了
如果接口定义的比较严谨理论上是不应该存在这种情况的不过凡事总有特殊这里举个接口不严谨导致数据被覆盖的例子。
假如OrderVO和OrderDTO有如下2个字段
/*** 已收金额* 单位分*/
private Long receivedAmount;/*** 备注*/
private String remark;正常情况下后端只应该使用前端传递的remark字段receivedAmount字段不应该使用但假如用户修改订单备注时前端不小心传递了receivedAmount字段并且赋值为null这时使用BeanUtils.copyProperties后OrderDTO里的receivedAmount字段就也为null如果后端不知道前端传递了这个字段并且操作DB不够严谨就会导致订单的已收金额被清空很恐怖而且不好排查原因。 4. 插件推荐
虽然BeanUtils.copyProperties工具提供了便利但带来的问题也很多因此很多公司包含我现在所在的公司都禁止在项目中使用该工具。
但重复的写对象转换实在是太繁琐效率太低了这里推荐一个IDEA的插件GenerateAllSetter可以一键生成对象的set方法非常方便如下图所示 插件使用
在需要生成set方法的对象上按快捷键OptionEnterWindows是AltEnter会看到下图所示的选项 点击后会自动生成所有字段没有默认值的赋值语句 如果生成赋值语句时想带默认值可以使用另一个选项 效果如下所示