记录开发小坑-实体类转Map&实体类复制

前述:

日常开发中对bean操作,有很多小技巧:

复制一个实体类的属性:

使用spring的bean工具类:

//org.springframework.beans.BeanUtils包下:
BeanUtils.copyProperties(空实体类对象,目标实体类对象);

apache的公用工具类:

也有复制目标实体类的属性到另一个实体类的方法:

//org.apache.commons.beanutils包下
BeanUtils.copyProperties(目标实体类对象,空实体类对象);

相比之下:spring的工具类只能复制实体类的属性到目标对象中,而apache的目标实体类还可以是map或者动态bean,底层会对其进行判断类型,来解析获取属性,并赋值。

BeanMap:使bean对象和map绑定,保持一致

org.springframework.cglib.beans:BeanMap
Bean转map&map转bean:

		import org.springframework.cglib.beans.BeanMap;
		
		public static void main(String[] args) {
        //创建bean对象
        User user = new User();
        //通过对象创建beanMap,使beanMap与user对象关联绑定
        BeanMap beanMap = BeanMap.create(user);
        //这样修改user,beanMap会随之改变
        user.setName("名字");
        log.info("对象转Map{}", beanMap);
        //这样修改beanMap,user会随之改变
        beanMap.put("age","11");
        log.info("Map转对象{}", user);
    }

本次出现问题的是我用的
apache的公用工具类org.apache.commons.beanutils包下:

将实体类对象转换成MAP:

Map<String,Object> map=BeanUtils.describe(实体类对象);

问题简述:

通过BeanUtils.describe(实体类对象);获取实体类的所有属性信息,并存到数据库中,但是这个实体类有日期格式,这个方法会将日期格式转换成字符串:Fri Aug 21 18:36:11 CST 2020这种格式,这样再将这个map作为参数传到dao层,执行sql就会报错:ORA-01858 数字格式的数据被非数字格式的数据填充。
但是我没有数字格式的字段,只有String和date类型的。通过debug才发现:
正常的时间字段应该转换成时间戳(毫秒数),这样的数字,所以才会报这个错误。因此使用工具类时,最好是查看其底层实现原理,确定是否有隐患。
解决方案比较简单:将时间格式转换好即可。

该方法底层源码:

原因分析

核心在ConverUtilsBean的convert方法,会将属性的值进行判断解析,如果是数组,则循环将每一个元素获取到再转换,如果不是数组,直接转换。
转换是通过Converter接口的实现类来完成,每种数据格式都有对应的数据转换类,比如日期的DateConverter.
但是他最后都通过这行代码转成了String。

converter = this.lookup(class$java$lang$String == null ? (class$java$lang$String = class$("java.lang.String")) : class$java$lang$String);

因此才会出现这个问题。

调用栈
convert:441, ConvertUtilsBean (org.apache.commons.beanutils)
getNestedProperty:716, BeanUtilsBean (org.apache.commons.beanutils)
getProperty:741, BeanUtilsBean (org.apache.commons.beanutils)
describe:514, BeanUtilsBean (org.apache.commons.beanutils)
describe:185, BeanUtils (org.apache.commons.beanutils)
核心方法
public String convert(Object value) {
        if (value == null) {
            return (String)null;
        } else {
            Converter converter;
            if (value.getClass().isArray()) {
                if (Array.getLength(value) < 1) {
                    return null;
                } else {
                    value = Array.get(value, 0);
                    if (value == null) {
                        return (String)null;
                    } else {
                        converter = this.lookup(class$java$lang$String == null ? (class$java$lang$String = class$("java.lang.String")) : class$java$lang$String);
                        return (String)converter.convert(class$java$lang$String == null ? (class$java$lang$String = class$("java.lang.String")) : class$java$lang$String, value);
                    }
                }
            } else {
                converter = this.lookup(class$java$lang$String == null ? (class$java$lang$String = class$("java.lang.String")) : class$java$lang$String);
                return (String)converter.convert(class$java$lang$String == null ? (class$java$lang$String = class$("java.lang.String")) : class$java$lang$String, value);
            }
        }
    }
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值