阿里,Mybatis一致命源码面试题结果集是如何实例化对象的
我们知道,MyBatis是一款优秀的持久层框架,它支持定制化SQL、存储过程以及高级映射。MyBatis避免了几乎所有的JDBC代码和手动设置参数以及获取结果集。MyBatis可以使用简单的XML或注解来配置和映射原生信息,将接口和Java的POJOs(普通的Java对象)映射成数据库中的记录。
可爱的小鸟,大家应该很熟悉这个小鸟吧
所以,就目前而言,MyBatis基本上是中小公司通用的持久层框架,简单,易上手,方便快捷,成为最受欢迎的持久层框架,远远甩开Hibernate几条街。
扯远了,回到我们文章的正题上来:
今天公司一同事出去面试的时候,阿里大厂面试官问了一个Mybatis源码上的问题,由于他没有注意这块,没有答到核心上,结果面试官直接终止了面试流程。很尴尬
面试问题:请描述一下,Mybatis是如何将查询结果集映射到实体类上的?重点阐述下实体类对象是如何构造出来的?
好吧,那我们就来对这个面试题进行分析一下,MyBatis是如何将数据库查询的结果集映射到我们的实体类上的,分析实体类对象是怎么构造出来的。
下面咱们就开始源码表演了
图1:直接进入到主题
上图中,handler就是Mybatis自己实现了JDBC标准接口Statement的一个子类PrepareStatement对象,该对象实际上是调用Connection。createStatement(sql)来获取的。
重点:大家注意看上图中红色线框地方的源码,那里就是对结果集和JAVA实体类的一个映射处理。我们进入到方法内部去看看它的处理逻辑
图2:handleResultSets方法处理逻辑
我们分析一下
【1】rsw:这里其实就是ResultSet的包装对象,包含了数据库结果集ResultSet,以及其它的一些元数据。
【2】resultMaps:这个实际上就是我们XML里面配置的返回对象,一般情况下只会有一条数据。所以,下面的while循环也只会循环一次,说到这里大家应该明白while的作用了吧,其实核心逻辑就是将数据库的结果集映射到我们需要的类型上去。
【3】handleResultSet:就是具体处理的方法,我们一路点进去,发现这里:
图3:这里就开始对结果集进行遍历
这个方法就是从包装对象rsw中取得ResultSet结果集,进行遍历,这个写法我相信大部分人都会,就是我们以前写JDBC的时候,循环设值是最基本的操作吧。
继续深入分析getRowValue方法,我们发现createResultObject方法
图3:创建结果集对象方法
这里有个重点对象:metaType,它是我们实体类的元信息,包括了字段信息,get和set信息,默认构造器等等。
那么metaType是怎么拿到的呢?我想大家都很清楚,那肯定是通过反射来获取的了。myBatis又是怎么获取的呢?跟踪源码我们发现,在MetaClass构造器实例化对象的时候,调用反射工厂来获取的,封装为reflector对象,里面就包含了我们类的元信息。具体信息如下:
图4:MetaClass的Reflector对象信息
好了,回到createResultObject方法,我们继续跟踪发现,myBatis需要进行自动匹配类对象的构造器。我们继续看createByConstructorSignature()方法,这个方法就是推断构造器的核心源码了。
图5:推断构造器核心方法
我们可以很明显的看到,myBatis分2步走,一个是拿到全部的显示构造器列表,一个是获取默认构造器。如果有默认构造器,则优先使用默认构造器;否则:就需要继续推断合适的构造器了。我们继续看看,是如何推断的呢?
图5:推断过程
好吧,看到这里,你觉得是不是很扯淡?myBatis居然是通过参数个数来判断的,而且只支持全参构造器,少一个都不行,最后的for循环仅仅是对参数类型进行了校验。这块确实不如Spring的灵活强大。
到这里,我们得到了实体类的构造器,回到MyBatis,看看是如何赋值的呢?我们先看看源码
图6:Mybatis赋值的核心方法
核心:这里就是拿到我们上面推断出来的构造器,遍历它的构造器参数类型列表,对构造器的每一个参数类型推断出一个类型处理器typeHandler,如:IntegerTypeHandler、StringTypeHandler。
我们继续看看具体的值是如何获取到的:ObjectvaluetypeHandler。getResult(rsw。getResultSet(),columnName);源码片段
我们看到,通过上面的类型处理器,从ResultSet中获取对应的字段的值,这个咋获取到的值,我就不说了吧,这个是JDBC的基础知识,即ResultSet。getString(column)来获取的。
循环体中,就是将每一个参数类型以及参数值一一对应放到constructorArgTypes和constructorArgs中去。循环结束后,调用objectFactory。create(resultType,constructorArgTypes,constructorArgs),你们知道这句代码是干什么用的吗?
哈哈,用大腿猜也知道,肯定是生成对象嘛,如何生成对象呢?
图7:生成对象的最终核心逻辑
O()O哈哈,看到这里,我们知道了MyBatis对数据库结果集映射的核心思想了,看到这里你知道该如何回答面试官的哪个问题了吗?
归根到底层,MyBatis用的是JAVA的反射那一套,没有什么创新的地方,以及对ResultSet的操作,也是很基础的知识了,这些我就不多说了。
我们可以看到,框架都是万变不离其宗,只有我们对JAVA的基础知道掌握好了,其它的框架还不是手到擒来。
祝大家能够吊打面试官,拿到高薪offer,赢取白富美,走上人生巅峰!
小米遭遇背刺,5100mAh144Hz,全新骁龙8旗舰仅卖2行业卷王的称号应该给谁?小米、realme还是iQOO?都不是!我觉得应该给联想拯救者,因为联想拯救者Y70这款全新的骁龙8旗舰手机性价比真的很高,是目前价格最低的骁龙8旗舰手……
大容山国家森林公园岭南一角的欧陆风光文本刊记者唐艺山高可及远,林深古木参,在广西玉林市主城交汇处,雄踞着桂东南第一高峰大容山。据《方舆纪要》卷108容县记载,大容山在县西北二十五里。高五百余丈,周围千余里。……
原创解读氧磷二烯酸还原酶基因的剂量差异调节小麦根系生长近日,研究论文Dosagedifferencesin12OXOPHYTODIENOATEREDUCTASEgenesmodulatewheatrootgrowth对12氧磷二烯……
8。如何维持正常的肠道功能1、营养均衡的膳食(一日三餐中包含蛋白质、维生素、矿物质、脂肪酸、膳食纤维等)2、充足睡眠(可以维持正常的人体免疫力,睡眠不足免疫力低下会使细菌有乘虚而入的机会)3……
致自己,这段话永不过期人活在世上不可能事事尽如人意,遇到困难和烦心的事情,听听别人的奉劝,也有好处。但是,化解心里的矛盾主要还是得靠自己,心烦时不妨想想下面这些话,或许有所帮助。01hr……
蟹蟹蟹蟹,这些螃蟹到底有何不同?在饭桌上能看到各种各样的螃蟹,这些螃蟹有什么特点和区别呢?原来还有一些是假蟹!蟹有很多部位不能吃,那能吃的有哪些?吃蟹要注意什么?我们一起看看吧吃蟹禁忌什么人……
人民日报每日金句摘抄1英雄模范,中华民族的闪亮坐标;功勋荣誉,激励前行的精神动力。2伟大时代呼唤伟大精神,崇高事业需要榜样引领。3一个有希望的民族不能没有英雄,一个有前途的国家不能没有……
荣耀80系列上手体验经典双镜设计,碧波微蓝呈现自然流动之美荣耀数字系列一直以来都以时尚潮流为出发点,为用户带来更高颜值的设计,这次全新的荣耀80系列也是如此,并且还邀请奥斯卡最佳艺术指导奖获得者叶锦添大师作为美学见证官,鉴赏这款东方审……
毛衣搭配裙子穿时,该如何搭配鞋子好看?毛衣是比较时尚、保暖、利用率很高的衣服,也是很多爱美女人的不二选择。尤其是春季,正是适合穿薄款毛衣的大好时节。那么,毛衣搭配裙子穿时,该怎么搭配鞋子好看呢?接下来就来学习8套时……
杜兰特1换9地震级交易,篮网梦想成真获6个首轮,勇士卫冕遇劲今日,森林狼给爵士的戈贝尔开出10换1的豪华报价后,篮球圈都在议论,连戈贝尔都能换回4个首轮签,杜兰特到底能换什么筹码呢?篮网总经理马克斯此前的底线是一个未来新星3个首轮签,而……
人纪之黄帝内经整理笔记01素问第一篇上古天真论【本章要点】l说明养生的积极意义。不仅可以预防疾病,而且是延年益寿的有效措施。l具体指出养生的方法:精神上的修养;饮食起居的调节;环境气候……
父母羞于启齿性教育,有人却在觊觎孩子们正在生长的身体最近发现一个可怕的现象:强奸案件的被害人竟然绝大部分都是十四岁以下的女孩子,年龄段基本分布在九到十三岁,还有少部分是智力有障碍的女性。而加害人从十几岁到八十多岁各个年龄阶……