mybatis面向接口编程实践与mapper代理对象的产生

上篇提到面向接口编程需要使用getMapper获取代理对象,今天我们来看一下mapper代理对象是如何产生的,在此之前先回忆下面试接口编程。
一、Mybatis面向接口编程实践
(一)使用xml的方式
1.定义mapper接口
Mapper接口就是一个普通的接口。
mybatis面向接口编程实践与mapper代理对象的产生
2.定义mapper映射文件
mybatis面向接口编程实践与mapper代理对象的产生
3.在全局配置文件中配置mapper映射文件
上篇我们也说过,虽有多种方式触发文件解析与接口注入,不做此步骤也能完成(搞清楚一个前提我们现在说的都是在mybatis面向接口编程方式下),但是我们建议通过配置映射文件的方式触发mybatis自动扫描注入。配置方式有多种,不在赘述。我们的配置方式如下:
mybatis面向接口编程实践与mapper代理对象的产生
4.现在我们测试一下
mybatis面向接口编程实践与mapper代理对象的产生
测试结果ok。
(二)使用注解的方式。
1.定义mapper接口,同时使用注解
mybatis面向接口编程实践与mapper代理对象的产生
2.接口注入。
上篇我们也提到过,虽然用注解不需要xml映射文件,但我们可以通过配置一个只含有namespace的映射文件触发接口注入。如下:
mybatis面向接口编程实践与mapper代理对象的产生
假如我们就是不配置,可以在使用之前调用
sqlsession.getConfiguration().addMapper(IUser.class);
3.测试,假设没有配置xml
mybatis面向接口编程实践与mapper代理对象的产生
测试ok.
二、Mybatis面向接口编程之mapper对象的产生

mybatis面向接口编程实践与mapper代理对象的产生
mybatis面向接口编程实践与mapper代理对象的产生
mybatis面向接口编程实践与mapper代理对象的产生
mapperRegistry中getMapper,首先通过Class类型在knowMappers中获取mapperProxyFactory.这个变量就是个hashMap,是所有注册的mapper接口,上篇我们提到过。方法直接返mapperProxyFactory.newInstance(sqlSession).我们接着看下
mybatis面向接口编程实践与mapper代理对象的产生
由此可以看出mybatis直接使用了jdk的动态代理产生了一个mapper接口代理对象。
MapperProxy就是是个InvocationHandler我 们看一下MapperProxy的invoke方法,
mybatis面向接口编程实践与mapper代理对象的产生
如果是object中的方法直接调用,比如hashCode,wait.toString…这些,我们接口中并没有default方法。最终会调用最后两行。
接着看下MapperMethod对象的产生

mybatis面向接口编程实践与mapper代理对象的产生
他有一个缓存避免了每次都重新生成一个对象,因为这个对象的创建过程比较复杂。
构造方法如下:
mybatis面向接口编程实践与mapper代理对象的产生
SqlCommand和MethodSignature为两个内部类,先看一下SqlCommand

mybatis面向接口编程实践与mapper代理对象的产生
里面如下方法是去全局配置对象查找解析的sql语句生成的类对象,id为接口全类名+方法名,for循环为递归调用,因为接口存在继承关系,方法不一定都声明在本类,也可能在父类,父类的父类。。。。。。。。
mybatis面向接口编程实践与mapper代理对象的产生
Come on
mybatis面向接口编程实践与mapper代理对象的产生
通过刚才的satementId取判断Configuration中成员对象mappedStatement中是否包含
mybatis面向接口编程实践与mapper代理对象的产生
这个对象便是所有解析的sql语句生成的类对象的map集合,为内部类,继承了hashMap,,重写了put,get方法。key即为namespace+语句id和语句id,两个key对应相同对象,这也是什么用mybatis的时候,语句可以不写namespace的原因。具体解析以后再分析。

判断如果存在对应的sql语句,则取到相应的MappedStatement对象,这个对象包含了映射文件中定义的语句(如select)的所有信息,比如参数,返回值,具体sql,类型(增删盖查)。。。等等等
内部类MethodSignature定义了接口中方法的各种信息。

mybatis面向接口编程实践与mapper代理对象的产生
至此MapperMethod对象完成创建。接下来调用execute方法。

mybatis面向接口编程实践与mapper代理对象的产生
该方法中根据语句类型,回归原始直接调用了sqlSession中的增删盖查方法,执行sql.根据配置和方法信息拼装返回结果。到此一个实现了mapper接口的代理对象生成完成,所以你可以尽情的使用此对象调用方法啦。