A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 大山哥哥 黑马粉丝团   /  2018-10-22 18:39  /  1292 人查看  /  3 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 大山哥哥 于 2018-10-22 18:56 编辑

          众所周知,我们在使用Hibernate、Mybatis等框架一系列的ORM框架的时候,我们都需要定义JavaBean类,用来和数据库的字段一一对应。但是当我们定义数值或者小数等能用基本类型表示的数据的时候,我们往往会将其定义为基本类型的包装类。例如下图

Student

Student


很多程序员,都知道这样去做,但是并不知道具体的原因。下面我从业务和技术层面去分析原因。
首先从业务层面来看
           以基本类型的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方法,执行即可。
具体做法如下图:

解决1

解决1

解决2

解决2
          经过上面的代码我们可以看到,其实这种特殊处理还是比较麻烦的,更重要的是浪费程序的执行效率,一些非常小型的ORM工具比如DBUtils,都是没有做特殊判断的,如果JavaBean类里面的属性是基本类型的,那么使用类似这种工具开发的代码很有可能是会报错的。但是像hibernate mybatis这些偏大型的ORM框架都做了完善的处理,但是刚才也说到了这种处理的执行过程也是比较浪费程序效率的。这也就是为什么我们日常开发的时候JavaBean类里面的基本类型属性都会定义为包装类的类型。
提取码:vsd5


3 个回复

倒序浏览
继续加油吧!
回复 使用道具 举报
毕业后,课程怎么更新呢?
回复 使用道具 举报
学习了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马