对mybatis执行过程比较好奇所以自己看一下执行过程
首先编写一个测试类,在对应生成代理mapper的地方,和执行语句的地方打上断点
首先看一下生成代理mapper的地方,因为getMapper返回的是一个接口,接口肯定是不会有执行方法操作的,所以,这里肯定是一个代理执行的操作对象。
往里走,发现调用configuration的getmapper方法
然后是configuration调用mapperregistry的getmapper方法,从中也可以看到对应的映射的mapper的类型
mapperregistory的getmapper方法,方法中调用了knownmappers的get方法
knownmappers为mapperregistory的内置hashmap
,可以看到hashmap中一共有五个,即使没有请求的mapper也在其中,
可见这个类是一个公共使用类,结合configuration,猜测应该configuration是一个单例公共配置类,为每一个sqlsession提供服务
通过type为key获取到对应的mapperproxyfactory,然后调用实例化
实例化的时候,可以看到使用了代理,对于mapperproxy进行了创建,使用mapperproxy对于原mapper方法进行执行,
然后跳到执行操作的地方,调用接口的方法
看到直接跳到了invoke方法,
这是mapperproxy对应的实现接口
在动态代理的时候,将mapperproxy传递给
proxy.newinstaence(类加载器,类的接口,实现了invokehandler的类),
在实现了代理的时候mapperproxy作为参数传进了这个方法里,当调用方法的时候,会进入到这个实现了invokehandler的类的invoke方法里
这里的第一个逻辑是判断方法声明是否为类,这个主要是为了对于继承了object超类的方法,例如这些方法肯定不会被代理的,所以这个主要是调用自己的方法
可见传过来的是一个接口方法,所以执行下面的判断,调用cacheinvoke方法,然后在调用iinvoke方法
可以看见返回的是一个mappermethodinvoke,然后调用这个类的invoke方法
对应的注解意思为
后面的代码是这样的,这一段看代码是对于java支持default方法,是否进行代理判断。
然后返回类调用invoke方法,invoke方法里面调用的是execute方法,
这里是判断执行的sql类型是啥,然后调用
然后调用的是
result就是查询出来的结果
然后对于结果进行转换