MyBatis源码(五)之动态Sql解析运行阶段参数处理

来源:互联网 发布:域名注册管理机构 编辑:程序博客网 时间:2024/06/07 05:59

上篇博文分析到Mapper文件的读取,以及启动过程动态Sql的解析部分 MyBatis源码(四)之mapper文件解析和动态Sql解析启动阶段

本博文继续动态Sql的解析,在运行时的解析。前文也提过,在动态Sql中,sql的最终生成是依靠传入的参数来决定的。所以在继续分析之前先来分析下是mybatis是怎么接收参数的。

dao参数上可能有@Param注解,参数中可能有集合Collection,如何跟之前配置文件中的javaType,parameterType对应起来等等。

dao的代理类MapperProxy的invoke方法,invoke能获取到拦截的方法的元数据信息和入参
去掉Object的方法之后拦截所有的dao方法。

跟进看下拦截Dao的方法是具体做什么的

MapperMethod

MapperMethod的一个成员MethodSignature,也是MapperMethod的内部类(mybatis的一个特点是比较喜欢使用内部类)重点看下参数部分:

MethodSignature

MapperMethod封装了被拦截方法的信息,包括:

返回类型是否返回多行是否有ResultHandler接口类型的参数被拦截方法的参数信息

如下dao方法对应上面的截图:

List<HrdDemandMatching> batchQueryBySellerIds(@Param("demandId")Long demandId,                @Param("sellerMemberIdLs") List<String> sellerMemberIdLs);

如果方法在有一个参数 就是 params就在添加一个key和value对 2= 2
key表示参数的下标2
value表示参数的名字(被注解@param标示) 没有的话value也是下标 即这里的 2 = 2
MethodSignature的这个params的TreeMap只是参数下标和名字而已,此时并没有放入参数,下面将参数填入参数值。
MapperMethod执行
MethodSignature将参数填入参数值

代理拦截方法之后委托给mapperMethod.execute还行,
covertArgsToSqlCommandParam这个方法将参数值和参数名对应起来,返回的是Object。

1)没有参数返回null2)1个参数返回args[0]3)多于1个返回Map,key:有@param注解的名字,没有param取下标

第三条除了将参数名和值放入map 同时又额外添加了一份参数的信息
如这里的param1和param2第一个下标参数的值,第二个下标参数的值,本博文后边还会用到这个!

其实MapperMethod.execute方法主要的是组织入参,选择执行SqlSession的那个方法 根据标签 select insert update delete和方法的返回值类型。

现在还没有完,还要方法参数转换成配置文件中对应的值和类型才完工。参数映射部分才刚刚开始!!
我们继续跟代码,这一步就是根据具体的 select insert等标签或者返回值决定调用那个具体的sqlsessionTemplate的方法(也是SqlSession的方法)
这里写图片描述
这里写图片描述
还记得吗 这里的SqlSession值的是谁?SqlSessionTemplate
SqlSessionTemplate的成员sqlSessionProxy – SqlSessionInterceptor,
SqlSessionTemplate也实现了SqlSession,所有的SqlSession方法都是用这个sqlSessionProxy 完成的,所有sqlSessionTemplate的方法都会被SqlSessionInterceptor拦截住,进而获取真正的SqlSession的实现,通过DefaultSqlSessionFactory.openSession创建DefaultSqlSession(SimpletExecutor,Transaction也都创建并且塞入到DefaultSqSession了)!!!这是如果忘记了可以看下之前的博文。
SqlSessionTemplate的成员SqlsessionInterceptor创建DefaultSqlSession
这里不再复述,只是贴下代码如读者回忆一下。

接下来进入到DefaultSqlSession的方法

DefaultSqlSession.selectList

DefaultSqlSession.selectList()方法SimpleExecutor.query方法的参数
wrapCollection(parameter)这个方法也值得看下:
dao方法超过两个会被当成map,两个以内是原生的对象类型,
该方法处理集合类型具体规则如下:

1、集合类型非map类型的直接map.put(“collection”,object);2、集合类型是List的map.put("list",object)3、数组map.put("array",object)

可见,只要超过两个参数的都会转成map collection和array的也不例外,都是map。

这里写图片描述

本篇将的主要是dao的参数是如何传入和处理的,贴图较多是为了让大家回顾下之前的流程不要看过忘了:

两个以内的参数都是不做转换,如果是collection的或者array会转换成map两个参数或者以上,直接转成map。

这里请求流程只是到了SimpleExecutor.execute
将dao的参数处理完毕了,但是参数是怎么跟sql中的入参对接上,以及sql是如何根据参数生成最终执行的sql还没有讨论。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 锅被腐蚀后变黑色应该怎么办 后厨炉灶里的炉芯进水了怎么办 小儿九个月老是流黄鼻子该怎么办 肉炖的老了不烂怎么办 吃了凉东西现在一直打嗝应该怎么办 喝了很多水还是觉得口渴怎么办 刚买的猪肝没洗直接炒了怎么办 四个多月的宝宝吃了脏东西怎么办 狗吃了脏东西拉稀呕吐怎么办 五个月宝宝怕吃药导致奶不喝怎么办 蒸锅锅盖吸住了怎么办锅比锅盖要大 豇豆没熟孕妇吃了中毒怎么办 孩子积食拉不出粑粑憋的直哭怎么办 2岁宝宝总是半夜拉粑粑怎么办 金毛拉很臭的稀粑粑怎么办 点餐系统登录后没有菜单怎么办? 环亚在线微交易亏了钱怎么办 钢管舞报了教练班觉得学不会怎么办 微信上聊天被外国人给骗了该怎么办 微信冒充朋友骗走我钱怎么办 凉皮调料水鸡精味精放多了怎么办 吃了地屈孕酮后月经不干不净怎么办 藕片用热水炒后变色了怎么办? 外汇延期收款忘了报告了怎么办 怀孕不小心吃了马生菜怎么办 高压锅的皮圈很容易坏是怎么办 华为应用市场账号密码忘记了怎么办 业主对我们提出批评意见时怎么办 向环保局投诉被公司发现了怎么办 在政务大厅上班被群众投诉怎么办 政府下发的文件通知不履行该怎么办 给私人老板开车不给工资怎么办 给个体老板开车不给工资怎么办 户口转走在人才市场的档案怎么办 外来媳妇转上海户口没有档案怎么办 公务员考试笔试差9分面试怎么办 想从事人事方面的工作没经验怎么办 教师资格考试后户籍转走认定怎么办 总经理离职了作为高管的我怎么办 企业换总经理想换供应商应该怎么办 换了晶振时间还快怎么办