本帖最后由 大山哥哥 于 2018-10-22 18:56 编辑
众所周知,我们在使用Hibernate、Mybatis等框架一系列的ORM框架的时候,我们都需要定义JavaBean类,用来和数据库的字段一一对应。但是当我们定义数值或者小数等能用基本类型表示的数据的时候,我们往往会将其定义为基本类型的包装类。例如下图
很多程序员,都知道这样去做,但是并不知道具体的原因。下面我从业务和技术层面去分析原因。 首先从业务层面来看: 以基本类型的int来举例。 Integer比较明显的一个好处就是 Integer比int可以多表示一个null, 你工作时可能遇到类似的情况,当一个用户注册时没有输入自己的年龄,用户注册成功后,个人中心显示年龄为0岁,随即用户打来电话进行投诉,说这是在侮辱他的人格。 当然案例虽然夸张了一些,但是这就是使用int的后果,因为当我们创建一个用户对象的时候,int类型的属性是有默认值0的,当用户输入了年龄生日籍贯唯独不想告诉年龄的时候,其他属性都设置进入了用户对象,而年龄这个int类型属性则变成了0。对应到数据库中则是0 。所以用户会看到自己的年龄是0岁, 当然这样的情况我们也可以写一些额外的逻辑判断处理一下。但是如果年龄是Integer呢,则Integer的默认值为null,对应到数据库中则为空,即没有数据。 还有一种情况是,对于很多ORM框架来说,逻辑是这样的,如果你的这个属性是主键,属性有值,框架则认为数据库里面有记录,则执行修改操作。属性没值,框架则认为数据库里面没有记录,则执行插入操作。而int永远有值,Integer则是可以为空的。当然你也可以写额外的逻辑判断处理一下,就是比较麻烦一些哦。 从技术层面上来说: 框架的底层都是调用JavaBean类的set方法进行赋值的。而基本类型属性的set方法则需要使用反射技术特殊处理。我们先从图片上查看为什么需要特殊处理。(图片中利用的Student类是上图的Student 类) 根据错误,我们的处理方向转变到了如何把Integer.class转变为int.class。 思路如下: 1 : 首先捕获NoSuchMethodException , 2:截取异常信息里面的Integer的全路径 比如“java.lang.Integer” 3:然后把其改为int.class, 4:重新获取Student的setAge方法,执行即可。 具体做法如下图: 经过上面的代码我们可以看到,其实这种特殊处理还是比较麻烦的,更重要的是浪费程序的执行效率,一些非常小型的ORM工具比如DBUtils,都是没有做特殊判断的,如果JavaBean类里面的属性是基本类型的,那么使用类似这种工具开发的代码很有可能是会报错的。但是像hibernate mybatis这些偏大型的ORM框架都做了完善的处理,但是刚才也说到了这种处理的执行过程也是比较浪费程序效率的。这也就是为什么我们日常开发的时候JavaBean类里面的基本类型属性都会定义为包装类的类型。 提取码:vsd5
|