00:00
好,那接下来呢,我们就来看马贝蒂斯处理参数的这一块源码,这块源码呢,是为了加深大家的这个理解,那么呢,作为一个理解内容,大家呃,下边也可以去研究一下。好,我们来看啊,那为了这个测试方便呢,我们就来调用这个方法,这个方法传了两个参数。传了两个参数,我们就来看它。MY,如何处理这些参数?好,我给这打一个断点来bug。好,进入咱们这得bug流程。那么进入这一块呢,我们首先知道我们规定了一个map接口。而我们调用了map接口的这个方法。然而这个member接口,MY会为他创建一个代理对象,所以说呢,最终都是代理对象去调用,嗯,去执行实现这个方法的。那我们就来深入这个方法的细节,好,Step into,它会先来到一个叫map proxy里边的这个work,而这个map pro我们也可以先来看一下,它是一个什么呢?哎,Invocation handle,就是动态代理的这个invocation handle。
01:17
好,它里的in work方法,我们当前要执行的方法,就是我们拿到了,就是我们这个get ep8id,哎,它这里边呢,有一个判断,如果说你当前方法啊,声明的这个类,你是在object类里边声明的方法,我们直接放行,否则呢,我们在这一块调用,就说我们我们这个代理对象。它是我们这个接口下的,那么它拥有我们这个接口下的这些方法。那么呢,它还拥有一些比如图斯string啦,哈西code啦这些object规定的方法,如果是这些方法,那就直接放行就行了,否则呢,哎,在这一块,嗯,人家调用了一下,先把这个man的包装成了一个map man的好啊,我们这一块呢,不是重点,我们就放过就行了,来看这一块它如何执行,我在这打一个断点,好,它如何执行的,我们传的参数是一。
02:16
哎,和汤。走。来到我们这一处,好,我step into进入,好,我们来看它怎么执行。在执行之前呢,他先判断了一下,哎,如果是哎添加它就调用这个,如果是更新这个,删除这个,而我们是查询,其实增删改查都一样,你看啊,每个在调用之前,这个result呢,就是返回值,哎,它会先muscle的第2CONVERT command。会把你传过来的参数先转换成我们SQL命令能用的这个参数,每一步都一样,包括我们这个查询,我们是查单个对象,哎,这块有判断,哎,如果你没有返回值,或者呢,你返回的是多个,返回的是map,或者返回的还是一个,咱们这个呢,嗯,说的这个游标,或者呢,哎,我们呢是这种啊,我们就直接返回一个单个对象。
03:16
他在这呢,哎,我们来看底层调用的还是circle session的这些增删改查API,只不过。人家这一块需要传入这个P,而这个P是通过我们传递过来的这个A转换得到的。好,我们放行在这。走好放线在这,我们这个传过来的参数是一和Tom,然后呢,它调用man的啊convert X好,我们来进入看它怎么。好,然后呢,它调用name。他调用这个点get name的S好图进入。啊,这一处就是我们,哎,咱们这个处理的代码,我们大家也看到了,诶P1P2就是说呢,它在这一块就是把每一个值封装成它原来规定的P1P2。
04:13
这一块代码我就写出来。大家在这哎,可以看一看,哎,大家注意的呢,就是我们是它是用这个name。Name。Name,咱们这个。解析咱们这个参数封装曼普的好,在封装的时候呢,这一块的代码我们也大致的跟大家走一走。他上手呢,先获取到一个names的size,而这个names是一个,哎。Collection map,这个map里边已经有值了,我们来看一下啊,这个map里边呢,是这个值。首先呢,我们把这个names的值贴出来,Names它的值是这个值,而这个值是怎么得来的呢?它是一个map k呢,就是零一,而Y6是ID last name,我们明显能感觉到这个ID跟last name,那就应该是我们这个map接口。
05:20
哎,我们调的是这个方法规定的这个。好,我们把这对比诶。对比大家来看。主要呢,我们就是有这么几个PAR标注,好,我们来看这个names它是怎么确定的,我们来可以看一下。Bug好,这names呢,它调用这个方法前就有值了,而这个值呢,这个names是我们这个p name的一个参数。而这个参数值得确定。好,参数值的确定,我们把它展开。在我们prime name这个只有一个有参构造器下,你看啊,有一段代码,哎,最终给names赋了个值,我们可以。
06:06
大概的来看一下。他先拿到所有的参数,以及每一个参数的注解,好他往下走啊,以及我们开始标注参数的索引,好你看他判断了一下。如果呢,我们当前参数的这个注解,它是P姆注解,它拿到注解的Y6值。并且呢,哎。相当于这里边叫汉字p not,哎拥有P注解,哎置为然后呢,它第一步。在这一块它第一步哎,拿到获取。获取。每个。哪个标了?嗯,注解的,咱们这个参数的。值,那么呢,你可能我们呢都标了,那就能获取到ID以及last name啊注解的值。
07:10
那么呢,他第一步会拿到这个,拿到这个以后呢,我们再来看。好,也就是说如果你这个没标注解,它就在这确定一下,哎。哎,它在这如果没标内呢,就等于我们这个map的这个长度。而这个map呢,每次确定一个参数,它会给map里边,诶index会放进一个东西呢,Map啊,每确定一个参数都会增大一下。它这一块的内相当于,哎,我们这个map的长度,就是我们这个参数啊。索引大小。好,然后呢,如果那么的值负值给。拿到这个PM的值,负值给我们这个name。啊,复制给一个,那然后呢,我们接下来,嗯,每次每次解析一个咱们这个参数,给我们一个map中保存信息,而保存的是什么信息呢。
08:10
这个信息呢,就是我们的这个参数的索引以及name值。哎,K就是咱们这个参数索引。哎,Y6就是我们这个。Name的值。而M的值啊,它会有一些情况,如果你标了P注解,那这就是。标注了。咱们这个盘主去。那么呢,就是注解指定的值。注解的值。那么呢,没有标注我们来看啊,如果没有标注,你这一块的name就会获取为空,它会有两种,哎,如果你全局配置,哎,这conflict代表是全局配置,全局配置有一个属性叫use actual,在我们官方文档里边,哎。
09:02
我之前来到setting这,哎,就是这个配置。就叫他是否使用咱们这个参数名,作为咱们真正的这个名字,这个呢,在JDK呃1.8诶的时候,我们这个反射才能获取到参数名,所以说呢。我们现在是获取不到的,这个方法也是拿不到的,如果你全局配了使用啊,Actual就能用。所以说呢,标注了。没有标注。没有标注。如果全局。啊,全局配置。配置了这个属性,这个属性呢,大家了解一下就行了,哎,咱们这个name,哎,就是咱们这个参数名。而我们没有配置,而且它的这个要求是JDK1.8的。我们现我现在用的版本是1.7。哎,是反射是拿不到参数名的,问他如果没有标注第一种情况,Name就是等于参数名,而我们现在拿不到第二种情况,那么这个name呢?哎,我们来看啊,直接就是这个map的大小,哎,你保存了几个元素。
10:17
你处理了一个元素,哎,你第一次处理那么就是零,第二次处理那么就是一,这个相当于就是相当于。他们这个当前这个元素。所以。啊,所以说呢,最终这个name里边,哎,就保存成这个样子了。出来了零一,因为它保存的时候K是参数的索引啊零一啊Y6值,如果你P标了就是P的没有的话。如果我们有第三个啊,假设我们传了第三个,我没标注解,那么就应该二啊,K是二,值也是二,就是这样。啊,所以说呢,这是names值确定好以后,它在这。
11:03
有一些判断。如果参数为空,哎,你这个本来你传过来的参数,我们现在X是有值的。二我们传了一个一。还传了一个套。我们传了两个值呢,那么呢,如果你这个参数为空,哎,它就直接给你返回为空。那直接返回。直接返回就行了。而这一块呢,另外来看第二个判断,它是如果你看啊。这个p count等于一,也就说我们这个names集合,嗯,这个names它是一个map,这个map里边如果它的这个大小是一,而我们现在有两三个,就说呢,如果只有一个元素。只有。一个元素。并且看好啊,并且它是没有爬注解。
12:07
注解,哎,它呢就会调用这个方法直接X。拿到我们这个names的第一个K,诶,Names如果只有一个元素的话,它第一个K就是零,相当于拿到咱们这二个零。也就是说呢,拿到我们这个第一个参数,而我们现在传了两个参数,当然不会进这个方法,所以说这一块我们略过。也就是说这一块就是我们所说的单元素。直接返回。单个参数。直接返回。哎,直接就交给你了,但是呢,你应该是没有注解的。如果你即使是单个参数标了注解,人家就封装map了,也就不走这一步了。我们来看第三个。第三步,第三步这一步呢,相当于就是多个元素。
13:01
啊或者呢,或者是有啊,咱们这标注。都会进入这一块,这一块呢,他上来先整一个map,然后呢,给这个map中保存数据。而这个map大家可以看一下,最终会进行返回,好,那这个map里边呢,保存数据。那么怎么保存呢?它是便利names。Names。集合。而我们这个names,我们刚才看了,哎,这是构造器的时候就确定参数的。吴早起。七的时候就确定好了。确定流程就是下边。确定流程就是下边,那么我们把这个names直接拿过来就用就行了,好。
14:00
它会变历这个names集合,而便利的时候呢,我们来看它会干嘛。他把每一次便利的好又放进这个map中,而放的时候现在看好。它是把这个entry.get y6,就是把这个map里边的Y6值拿过来当为K,所以说呢,Names集合的value座为K。那么这样的话,我们刚才帕姆确定的值就会作为K了。而值呢,就是我们又把这个零一索引。集合的K啊。又作为取值的参考。也就是说呢,这个K因为是索引零,一,所以说它直接从二,零,二,一就来取出我们对应的值。我们二个传了好多啊,这个arguments就是说这个参数传了好多。
15:04
那么这个二个有这么多,那么它遍历完以后,Y6作为K,那么呢,最终就会封装成我们这个效果来看啊,Y6作为K和第一个ID,而值呢就是二。二取出的,哎,我们索引X0。那么这样的话呢,ID就取出一了,哎,它最终就保存成IDE。I,哎,就是它,那么呢,而我们第二个Y6又作为k last name。哎,然后呢,它就取取出来是我们这个二。1X1,也就是我们的Tom啊,我这么来写啊,等于X0,也就是。也就是我们的一。那么呢?假设我们有第三个参数,我们并没有M。还是看之前,假设我们有第三个参数,那值是二,哎,我们第三个参数我们传入了一个ABC。
16:07
我们传入了一个哈,假设我们有第三个参数啊,但是我们并没有标注解,那么这个names的集合啊,就会是这样。第三个参数,哎,是所以是二没标注点还是这样,那么呢,我们第三个参数,它就会封装成二等于我们这个,哎,第三个参数。哎,它的K就是R等于R的。而拿这个。K啊,Y6是作为这个K,而那这个K又作为我们这个R格的取值啊,这是我们这个假设啊,这是一个例子,说这样这样的话呢,这个P里边就有值了,然后把这个返回我们井号大括号ID就能取出它,井号大括号拉name就能取出它,所以说就是这样。而额外还多了一步,你看啊,它有一个gene name,这个name。
17:07
我们来看一下。啊,这个呢,就是palm,它有一个palm前缀。比如说呢,这一块他又处理了。哎,相当于,哎,相当于这块呢,它把每一个参数除过按照你要求,哎,你标的注解外放外,它额外的。额外的将每一个参数也保存成保存到map中。使用使用。咱们这个新的K,而这个K呢,就是我们这个P1,一直到PN,所以说呢,最终我们的效果就是。效果就是我们呢,有注解,有他说我们注解。可以井号大括号,咱们这。
18:03
啊,咱们这指定的K。指定的K就能拿得到,或者不管你有没有直接井号大括号PAR12也能拿得到,哎,这一块呢,人家也重新封装了,封装的这个值就是帕一二,诶前缀加上当前这个123,哎这么来索引,而这一块呢,它不是从零开始的。哎,我们是从帕一帕二开始的,所以说大家注意啊,这就是我们这个参数处理,我们把代码呢,大致的给大家分析了一下,大家也可以仔细往下看。
我来说两句