使用这两个工具类需要引入的maven jar包依赖
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.3</version>
</dependency>
beanUtils工具类
使用beanUtils拷贝属性的实体类需要有以下条件:
1. BeanUtils解析的bean必须被public修饰
2. bean必须提供空参的构造器
3. 成员变量必须被private修饰
4. 必须提供set get方法
javaWeb开发过程中,经常需要在领域类之间进行实体对象的拷贝操作,比如把Po类的属性值拷贝给Dto类。
BeanUtils这种工具类应用而生,比如org.apache.commons包中的BeanUtils就提供copyProperties(Object dest, Object orig)方法,它方便开发者快速在俩个对象之间进行字段值的拷贝。而且,拷贝条件非常简单:拷贝实体类之间只要保证字段名称一样即可。
尽管BeanUtils好用而且便捷,将开发者从繁重的get set操作中解放出来,但是笔者不太推荐使用他,原因有三。
1. 字段名必须一样
虽然俩个拷贝类之间,需要拷贝的属性字段名必须要一样,当它们字段值不一样的时候,这时候就需要手动获取并赋值。当俩个实体类存在个别字段不一样时开发者容易忽视他,而忘记手动设置。
比如Po类的用户名叫 uName(数据库字段u_name),而Dto类因为是给其他模块调用的所以写有阅读意义的全程userName,这时候我们就必须手动设置
dtoObj.setUserName(poObj.getuName())。
2. 性能问题
BeanUtils内部实现采用的是反射功能,当反射的操作数量达到万级别的话,耗时非常明显。笔者亲自试过,对五万条数据进行拷贝操作,能明显感觉到卡顿。所以说BeanUtils是一个用性能换时间的得不偿失的买卖。
3. 泛型擦除问题
在进行集合直接的数据拷贝时,因为泛型擦除问题,导致拷贝失效。比如我们需要将Po集合列表转化为Dto的集合,因为泛型擦除问题,最终得到的还是Po的集合。
BeanUtils.copyProperties()和PropertyUtils.copyProperties()的差别
-
无论是org.springframework.beans或者org.apache.commons.beanutils,与get/set方式相比,都存在性能问题。
-
效率由高到底:get/set 》PropertyUtils 》BeanUtils。
-
PropertyUtils和BeanUtils两个工具类都是对bean之间存在属性名相同的属性进行处理,无论是源bean或者是目标bean中多出来的属性均不处理。
-
具体来说:
BeanUtils.copyProperties()可以在一定范围内进行类型转换,同时还要注意一些不能转换时候,会将默认null值转化成0;
PropertyUtils.copyProperties()则是严格的类型转化,必须类型和属性名完全一致才转化。
对于null的处理:PropertyUtils支持为null的场景;BeanUtils对部分属性不支持null,具体如下:
a. java.util.Date类型不支持,但是它的自雷java.sql.Date是被支持的。java.util.Date直接copy会报异常;
b. Boolean,Integer,Long等不支持,会将null转化为0;
c. String支持,转化后依然为null。
- BeanUtils的高级功能org.apache.commons.beanutils.Converter接口可以自定义类型转化,也可以对部分类型数据的null值进行特殊处理,如ConvertUtils.register(new DateConverter(null), java.util.Date.class);但是PropertyUtils没有。
另外:值得注意的是,在测试过程中发现,commons-beanutils-1.8.0.jar版本中的BeanUtils类,支持Byte到Integer或int的转化。说明实际使用过程中,我们还是要多看源码,多做测试,并且注意版本号升级带来的微小变化。