00:00
好,那我们刚才呢,咱们是讲了my be获取参数值的这第五种情况,那咱们所使用的是咱们的a per这个注解啊好,然后下面呢,大家来看,那我们当前这个a per这个注解的效果是什么呀?是不是my be会将参数放在一个map集合中,以两种方式来进行存储,以a per注解的值为键,以参数为值,以A以PER1PER2为键,以参数为止,对吧?那它到底会为什么会有这样的一个功能呢?所以说咱们讲到这个地方了啊,那咱们就通过源码呢,去验证一下咱们当前所说的这个过程,OK吧,好啊,行,那所以说我们该怎么从哪去打断点呢?大家想想,那我们当前是不是应该是在这个方法上打断点,因为我们的map接口,咱们创建的只有接口,我们有没有创建实现类呢?没有,那所以说实现类也就是这个方法具体的实现过程是由咱们的my be提供的,对不对?那所以说咱们就要来看一下my be在执行这个方法的过程中,它到底都干了什么,OK吧,好啊,行,那下面呢,大家来看我们当前呢,咱们以debug的方式来执行,然后我们就可以进入到我们当前的断点模式中,OK啊,来,然后下面咱们进入到这个方法里面啊,大家看一下这几个。
01:26
按钮首先呢,这个是什么?叫做下一步,这个是进入到某个方法中,这是强制进入,然后这个是从某个方法中返回,然后这个是返回上一个断点,然后这个是跳转到我们的光标所在的这一行啊行,然后下面呢,我们进入到这个方法里面,大家来看啊,然后这个方法叫什么?叫做map proxy,然后点Java,所以说咱们在讲get map方法的时候,咱们说了它的底层用是谁啊,它的底层用的是代理模式啊行,然后下面呢,我们再往下走,咱们走到这儿,大家看一下这个叫catch的in voer,这是跟咱们的缓存相关的,对不对?然后这个呢,是我们当前一个方法的执行,所以说我们现在咱们进入到哪个方法中,咱们进入到这个方法中,因为咱们的缓存呢,大家注意,你既然是要从缓存的方法中去执行,那我们是不是必须得提前查过,然后我们是不是才会有缓存的结果。
02:27
对不对,所以说咱们在这看这个look方法就行啊,好,然后大家来看,那现在呢,它是给了我们一个选择,因为这里面一共有两个方法,所以说我们现在咱们应该是访问的这个方法,咱们点击一下就可以啊,然后进来之后大家看这个叫map method map指的是咱们的映射,指的是map接口啊,Method指的是方法,它其实指的就是我们当前咱们的map,咱们的map接口中方法的一个执行过程,大家来看啊,那行,那下面咱们再进入到这个方法里面来,大家看在这儿呢,它咱们看到的是一个Switch case。
03:06
来判断我们当前咱们的一个操作,然后大家注意在这个地方有一个叫做它判断的是谁呢?叫做common common表示的是什么?表示的是命令,表示的是指令的意思,咱们鼠标放上去,然后大家来看看这个command里面只有两个数据,一个数据是我们当前咱们要执行的circle,一个代表的是我们当前咱们circle的类型,大家看好啊,这个是我们要执行的circle,那其实我们在之前呢,然后咱们在报错,咱们在昨天吧,咱们在讲的时候,有一个报错的地方,咱们就看到了,他说的是我们当前咱们的一个circle口语句报的错,而他给我们指向的是不是就是一个中间有各种对吧,一是应该是一个啊全类名的方式,然后给我们展示出来的一个circle,对不对,那大家注意,我也跟大家说了,这个东西就是我们买be中某一个circle语句的标识。
04:05
这个大家看好了啊,某一个SQL语句的标识,这个标识怎么来表示呢?很简单。大家注意,我们的命名空间来表示的是映射文件的唯一标识,而我们的circleql语句的ID表示的是circle的唯一标识,所以说这个circle的唯一标识应该怎么来表示呢?命名空间点circle的ID,而命名空间指的就是咱map接口的全类名,而so口语句的ID指的就是咱们的方法名,大家来看是不是com.I的硅谷点my be.map.parameter map.check log by。Para。能看懂吧,这是咱们的my be中circle语句的唯一标识啊,这个大家注意,然后再往下是咱们circle的类型是什么类型查询,然后下面大家看它,根据我们当前这个circle的类型呢,来进行了一个判断,如果说是insert,则执行它,如果是update则执行它,如果是delete,则执行它,而如果是select select的话,那执行的是这旮的代码。
05:13
所以说大家也可以看看一下,咱们哪一个功能其实是最复杂的呀,查询。好,然后大家来看,那下面呢,那我们当前咱们的这个操作不是查询功能吗?对不对,所以说咱们一个执行,大家看断点是不是就走到这儿了,然后来判断我们当前咱们这个方法的返回值,那咱们当前咱们的方法是谁呀?方法指的就是咱们map接口中的方法,如果判断它的返回值没有返回值对吧,然后来判断它返回的有多条数据,返回的是一个map。能看懂不,然后return的是一个cor对不对,然后或者说是其他情况,那我们现在咱们查询出来的应该是谁呀,大家来看我们下面咱们来一个直行对吧,大家看一下都不满足,再往下来再往下大家看都不满足,所以说就走到这儿了。
06:07
然后这里面呢,它在调用我们当前这个方法的时候呢,大家看好,它先执行了一个这样的方法,叫做convert,是转换,转换我们当前咱们的a as指的是方,指的是参数,对不对?然后to circle command para什么意思,将我们当前的参数去转换成咱们的circle语句的参数,能看懂吗?这不就是买杯,这不就是咱们的买be体获取参数值的这个过程吗?把我们方法的参数转换成咱们的SQL语句的一个参数对不对?好,然后下面大家看,那这个参数是谁?那大家说这参数不就是我们调用的方法的参数吗?里面一共有两个值,一个是order的me,一个是123456,对不对?大家再看一眼,你看看这里面,然后我们在底层里面,咱们看到的这两个值对不对?你知道这参数名叫啥?不知道这里面有跟参数名相关的内容吗?没有,咱们传输到my be里面之后。
07:08
咱们只知道参数值是什么,知道吧,哎,这个大家注意啊,好,然后下面呢,我们再往下,那咱们就只需要来看一下咱们这个方法里面是怎么写的就行啊好,进入到方法中,然后大家看又调用了一个方法,那咱们再进入到这个方法里面,OK就可以了,然后咱们看到这儿呢,然后大家会发现这个地方他先去操作了一个内姆S,那这个names是谁呢?那咱们也不清楚,那所以说咱们是不是就得去找到谁啊,去找到我们当前咱们的这个类里面声明names的地方,因为我们要看这一段代码,咱们首先要知道names是谁,对不对,所以说咱们先来找到names,大家看这是一个map集合。然后哪一个地方来为names赋的值呢?然后咱们再往下看,大家来看一下啊,然后就在这个地方,这个地方就是为咱们的names来进行赋值的,那换句话来说,咱们当前的这个方法,那不就是来获取咱们的names的吗?对不对,那大家来看,那我们当前的names里面都放了什么啊,好,首先大家看一下啊,这个叫做para name对吧?然后叫做参数名,这是我们当前咱们的命名参数的一个解析器啊好,然后第一行呢,咱们不管啊,然后大家来看咱们的第二行,这是我们当前咱们的method,其实就是我们所调用的方法,咱们map接口中的方法,然后来获取了它的参数类型。
08:41
来获取了它的参数类型,大家来看一下,这个是我们当前反射中的一个方法啊,它的返回值呢,然后是一个class类型的数组,首先为什么是数组,因为咱们一个方法它的参数可能有多个,所以说这是一个数组,而获取的最终的结果呢,是class类型,也就是我们当前参数类型的class对象。
09:08
OK,再往下来获取我们当前这个方法的什么叫parameter or notations什么意思啊?是我们当前这个参数所对应的注解啊,大家会发现这是一个二维数组,为啥呀?因为咱们的参数有多个,那我们当前标识一个参数的铸解是不是也有可能有多个呀?所以说大家注意,咱们的第一位数组中放的是我们当前咱们的参数,然后第二位里面来放的是我们每一个参数所对应的多个注解,这个大家注意,所有注解可能没有,也有可能有多个啊。然后下面在这儿呢,他创建了一个map集合。然后再往下大家看,然后在这它是不是来获取了我们当前咱们的这一个变量,然后它的一个什么呢?一个长度啊,Final应该是常量对吧?然后这一个常量它的一个长度,然后其实在这咱们获取的是点lengths啊,点lengths指的是一维数组的长度,所以说在这咱们获取的应该是参数的个数,这个大家注意叫pair count,然后下面在这就进行了一个for循环,对不对?大家看好,这个for循环是用来干什么的啊,首先呢,大家看好叫para index等于零,Para index小于per count,那其实咱们看到这儿咱们就知道了,它肯定是干什么的,来对我们当前咱们的参数,参数类型以及参数所对应的注解类型来进行循环的。
10:44
对不对,首先呢,它先判断了我们当前咱们的这个参数的类型,是不是一个特殊的参数,这个咱们不用管啊,好,然后再往下,然后定义了一个name,然后声明了一个name,这个变量等于null,然后下面来对我们当前咱们的每一个参数,大家注意啊,来看,好,然后我们当前咱们。
11:08
这个东西啊,这是不是应该是我们当前的这个常量对不对,然后加上方括号,是不是应该是来获取。我们当前咱们的每一个一维数组所对应的数组是不是啊,对吧,也就是说来获取我们当前咱们的每一个参数的所有的注解来进行循环。对吧,然后大家来看,然后咱们现在呢,对注解进行循环呢,咱们循环出来的就是注解对象,然后下面来判断这个注解的类型啊,如果是P,然后咱们就来把一个变量的值,然后来设置为处,那这个变量的值,这个变量是在哪的呢?大家来看一下,是不是也是设置的是一个成员变量对不对,它的它默认是没有值的,对吧?那我们在这儿,如果我们当前咱们有任意一个参数,它的注解,然后是per类型,大家看它的值是不是就会变为true。
12:05
是不是,然后下面来对我们当前的注解进行强转,转换完之后来获得它的Y流属性值,那大家说这不就是咱们当前咱们的a per这个注解的Y流属性值吗?对不对。能看懂吧,好啊行,这个大家注意,然后当我们获得了它的value属性值之后,咱们直接跳出啊,直接break。能看懂不,在这大家注意直接break,但是我们在这所break的的是我们最外边的这一个for循环吗?不是,而是我们当前咱们的这个for循环,那换句话来说,咱们只要检测到某一个参数上有a per注解的话,那我们是不是当前这个for循环就直接结束了呀,对不对?然后再往下看,如果它恒等于空怎么的,那咱们不等于空对不对,然后再往下,如果不等于空怎么办?它会把我们当前咱们的内幕,也就是咱们a per注解的value属性值给放到一个map集合中。
13:10
以什么为鉴?Para index,这不就是参数的索引吗?对不对,大家来看参数的索引,然后以什么为值,以a per这个注解的值为值,OK吧,好,大家注意,这是我们的第一次循环,那所以说第一次循环大家说这个map里面应该放的是谁啊。啊。应该放的是谁?大家想一下,应该放的是零和username吧。对不对,这不是参数的索引吗?那咱们当前的第一个参数索引为零吧,然后咱们往里面来放的是不是应该是咱们a per注解的value属性值,那所以说咱们的第一次循环结束之后,这个map里面来放的不应该是零和username吗?也就是咱们这个值啊,对吧?然后咱们第二次循环之后,这个map里面放的应该是一和谁啊,一和password对不对?然后这个循环执行完之后,他把我们当前咱们的这个map集合进行了转换,转换成了咱们的name names,那换句话来说,其实这个map跟这个names这里面存储的数据是一样的。
14:22
大家可以来看一下啊。好,咱们鼠标放上去之后,大家来看是不是0USERNAME1PASSWORD呀,是不是好OK,咱们现在知道了names长得什么样,那我们下面咱们是不是就可以来找到我们的这一段代码了,对不对?names.size大家看一下,这不就是我们刚才要看的这一段代码吗?但是我们现在咱们是不知道names是谁,所以我们刚才咱们就把获取names的过程咱们看了一遍。那下面咱们是不是就可以看这一段代码了啊,Namemes里面放的是啥?大家还有印象吧,0USER nameme1password,然后在这它定义了一个para框的叫做参数,个数是names的长度,那不就是二吗?对不对?然后再往下执行,大家来看啊,然后他来判断,如果我们当前咱们没有参数,这个二大家还记得二就是这个方法的真实参数,一个是零奥的幂,一个是1123456对不对?如果当前咱们的二恒等于空,那很显然不等于空,然后咱们再往下走,走到这儿,然后大家再看,如果我们当前咱们是没有什么的,看这个啊,Has para on,大家还记不记得这是在哪的?这东西是不是当我们去检测到咱们有这个a per注解的时候,它的值是不是就为触了。
15:48
对不对,那所以说我们当前咱们的这种情况,它是不是应该也是处,那它是处加了反之后,加了叹号之后,那它就是false,那所以说这个if是不是应该也不成立,对不对?然后下面呢,我们再往下看来看到这儿它又又又又定义了一个map集合,然后在这声明了一个I等于零,然后下面对我们当前咱们的names来进行了一个循环,对不对?来对其中的键值对entry set来进行了循环,然后下面大家看它都干了点什么,往我们的这个para map集合里面,然后来放了一个键值,对第一个键值,对啊,首先键为什么叫NT,垂点get value,那不就是咱们name名。
16:37
那不就是我们names这个map集合的value吗?大家说names map集合的value是谁啊?这里面存的不是零对应user name1对应password吗?那所以说这个东西不就是username和password吗?是不是?然后as方括号,大家说这又是啥?ATS指的是我们当前这个方法的真实参数,指的是零额的IN1。
17:05
123456对不对,然后arts方括号这里面,因为它是一个数组嘛,对不对,所以说我们要想来访问,咱们应该用下标,而这个下标指的是谁?指的是咱们entry里面的键,那这个键又是谁呢?简单呀,零对应u name嘛。是不是键是零,然后值是u.name所以说咱们放到这个map即可里面的时候,那我们的这个键是不是user name,这个值是谁呢?值是ATS0,而ATS0指的不就是咱们参数中的第一个吗?所以说这是user nameme,这是a me,来大家自己看啊,首先咱们找到咱们的namemes,大家看一下啊,然后这里面咱们的这个数据啊,来大家看是不是0USERNAME1PASSWORD呀,所以说咱们来获取entry的value,那不就是username吗?然后它的N垂的键,那不就是零吗?ARGS,然后不就是咱们的A的in和123456吗?所以说AGS,零,那不就是order me吗?所以说咱们执行到这一句话的时候,咱们的paras里面就有了第一个键指对是username,然后order me。
18:22
来,咱们往下走,大家来看,走到这鼠标放上去之后,大家来看一下是不是username or me。没问题吧,然后再往下的话,大家看看这他给我们声明了一个变量,字符串类型的变量,然后叫什么呢?叫generic name prefix,那这个东西是我们自generic是生成的意思对吧?然后name名字,然后前缀对不对,这个叫我们生成的命名前缀,鼠标放上去叫做per,然后加上A加1A是不是等于零啊。是不是啊,所以说在这那这个值的结果不就是PER1吗?大家来看我鼠标放上去是PER1吧,然后他干了点什么,他判断了一下我们names里面是否包含有PER1这个值,如果有的话怎么的,如果没有的话怎么的,大家说前面加了一个叹号,应该是有还是没有啊,应该是如果没有的话,是不是才会执行这一句话,而这一句话是不是又往咱们的per里面去放了一个键值,对,而键就是咱们的PER1,而这个值是不是跟上面这个值是一样的,也是a me,所以说为什么咱们讲第五种情况的时候,咱们说了,那my be把数据放在map集合里面是两种情况呢?一种是以per注解的值,一种是PER1 per2,大家注意,答案就在这儿啊。
19:50
看到了没?这就是我们最终咱们map my be,然后所生成的这个map集合,以两种方式来存储咱们当前的数据,第一种a per的值为键,以参数为值,第二种PER1 per2为键,以参数为止。OK吧,咱们来往下看,看完了啊来这个时候咱们的per里面两个键值,对对吧,PER1OLD me。
20:16
是不是,然后下面I加加之后,然后再次来进行循环,那这个时候咱们的I。应该等于几了,是不是就等于一了呀?对不对,然后等于一了之后,我们下面咱们再往下,这个时候咱们是不是应该来循环的是咱们names里面的第二个键齿,对对不对,那所以说这是不是就是password,这是不是就是123456啊,然后再往下,哎,大家知道这句话什么意思,不知道不知道。他在这判断的是谁啊?他在这来判断的是我们当前咱们的a per这个注解的值是不是本身就是PER1和PER2,如果说本身就是PER1和PER2的话,它就不再往map集合里面就放了。
21:03
能听懂吧,然后如果要不是PER1和PER2的话,那它就会再往里面以PER1和PER2的方式来存储一个键值,对。知道吧,这样的啊,好OK,然后下面呢,我们再往下看,然后这个时候大家看,因为大家注意这个地方是A加一啊,所以说咱们的per第一次循环,这是PER1,第二次循环这是PER2啊这个大家注意行OK,那我们现在咱们执行完了,咱们的per里面就有了四个建制队,分别是PASSWORD123456 per1a me user nameme me per2123456。这个大家注意,这不就是我们跟大家说的这个结果吗?是不是来找到我们当前咱们的测试类。使用A注解命名参数,My be会以两种方式把这些数据存储在map中,以a per注解的值为键,以参数为值,以PER1PER2为键,然后以参数为止,OK吧,好啊,行,大家注意,这个就是我们的一个a per注解在源码里面的一个解析啊,然后这个大家也是简单了解一下就行,OK吧,啊,然后咱们呢,其实在讲源码的时候,其实就是一个验证的过程,我们已经知道结果了,咱们从源码里面呢,咱们能能够来看到这个过程就可以了啊,大家没有必要说把这里面的每一行都看懂,没有必要咱们只需要通过源码去验证我们最终的一个结论就行啊。
22:38
好,OK。
我来说两句