为什么Mybatis只需要接口就可以执行sql?
sqlSession.getMapper()
我们看到下一步是sqlSession.getMapper()获取Mapper的代理对象,这个方法的具体实现如下
configuration.getMapper()
mapperRegistry.getMapper()
mapperProxyFactory.newInstance()
我们再来看看mapperProxyFactory.newInstance()做了什么
我们可以看到通过代理工厂获取了mapper的动态代理对象。
插入小知识:https://www.yuque.com/docs/share/d4e1bc97-7899-4108-90a1-d81a69395fba?# 《【3-0】动态代理》
动态代理的拦截功能
动态代理对象执行listAllUser()方法,是经过mappeProxy(newProxyInstance的第三个参数)反射调用,执行的具体代码是:
其首先判断一下执行的方法是不是Object里面的方法(因为所有方法都会走invoke,包括Object中的equals、hashmap方法等),如果是则直接执行,如果不是则执行cachedInvoker方法,该方法具体比较复杂,但是其返回值比较简单
返回了一个MapperMethodInvoker,其静态代理的MapperMethod对象,具体代码如下:
mapperMethod.execute()
执行invoke方法即是执行mapperMethod.execute()方法
我们来看一下execute方法是如何执行sql而不需要方法体的吧!
其中主要的思路是:判断传入的Sql类型,让后调用converArgsToSqlCommandParam方法,然后调用sqlSession的insert、update、delete、selectList等方法。其实insert、delete底层都是调用的update方法,所以一共就两类方法一种是update、一种是select方法,但是select有很多不同的方法,我们一起来看一下吧。
sqlSession
最终进入SqlSession的以下方法

剩下的我们以后再讲吧~
总结
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper最终生成的是一个代理对象,该代理对象是由sqlSession->configuration->mapperRegister-> mapperProxyFactory利用动态代理生成的
List<UserEntity> userList = userMapper.listAllUser();
userMapper是一个代理对象,其调用任何方法都会经过invoke()方法,执行任何非Object继承过来的方法,会有MapperMethodInvoker.invoke()执行,最终会调用sqlSession的select和update相应方法
