Mybatis面向接口编程实践与mapper代理对象生成

上篇提到面向接口编程需要使用getMapper获取代理对象,今天我们来看一下mapper代理对象是如何产生的,在此之前先回忆下面试接口编程。

一、Mybatis面向接口编程实践

(一)使用xml的方式

1.定义mapper接口

Mapper接口就是一个普通的接口。

[图片上传失败...(image-f682a9-1542177065563)]

2.定义****mapper映射文件

[图片上传失败...(image-7f393e-1542177065563)]

3.在全局配置文件中配置mapper映射文件

上篇我们也说过,虽有多种方式触发文件解析与接口注入,不做此步骤也能完成(搞清楚一个前提我们现在说的都是在mybatis面向接口编程方式下),但是我们建议通过配置映射文件的方式触发mybatis自动扫描注入。配置方式有多种,不在赘述。我们的配置方式如下:

[图片上传失败...(image-994100-1542177065563)]

4.现在我们测试一下

[图片上传失败...(image-459231-1542177065563)]

测试结果ok。

(二)使用注解的方式。

1.定义mapper接口,同时使用注解

[图片上传失败...(image-70796f-1542177065563)]

2.接口注入。

上篇我们也提到过,虽然用注解不需要xml映射文件,但我们可以通过配置一个只含有namespace的映射文件触发接口注入。如下:

[图片上传失败...(image-cb2a30-1542177065563)]

假如我们就是配置,可以在使用之前调用

sqlsession.getConfiguration().addMapper(IUser.class);

3.测试,假设没有配置xml

[图片上传失败...(image-e96573-1542177065563)]

测试ok.

二、Mybatis面向接口编程之mapper对象的产生

[图片上传失败...(image-d97754-1542177065562)]

[图片上传失败...(image-cbb021-1542177065562)]

[图片上传失败...(image-2ff428-1542177065562)]

mapperRegistry中getMapper,首先通过Class类型在knowMappers中获取mapperProxyFactory.这个变量就是个hashMap,是所有注册的mapper接口,上篇我们提到过。方法直接返mapperProxyFactory.newInstance(sqlSession).我们接着看下

[图片上传失败...(image-201955-1542177065562)]

由此可以看出mybatis直接使用了jdk的动态代理产生了一个mapper接口代理对象。

我 们下面看一下MapperProxy,的invoke方法,MapperProxy是个InvocationHandler

[图片上传失败...(image-40c7b4-1542177065562)]

如果是object中的方法直接调用,比如hashCode,wait.toString..这些,我们接口中并没有default方法。最终会调用最后两行。

接着看下MapperMethod对象的产生

[图片上传失败...(image-d07275-1542177065562)]

他有一个缓存避免了每次都重新生成一个对象,因为这个对象的创建过程比较复杂。

构造方法如下:

[图片上传失败...(image-13faaa-1542177065562)]

SqlCommand和MethodSignature为两个内部类,先看一下SqlCommand

[图片上传失败...(image-e275e2-1542177065562)]

里面如下方法是去全局配置对象查找解析的sql语句生成的类对象,id为接口全类名+方法名,for循环为递归调用,因为接口存在继承关系,方法不一定都声明在本类,也可能在父类,父类的父类。。。。。。。。

[图片上传失败...(image-4abb5b-1542177065562)]

Come on

[图片上传失败...(image-d4fb92-1542177065562)]

通过刚才的satementId取判断Configuration中成员对象mappedStatement中是否包含[图片上传失败...(image-8ae882-1542177065562)]

这个对象便是所有解析的sql语句生成的类对象的map集合,为内部类,继承了hashMap,,重写了put,get方法。key即为namespace+语句id和语句id,两个key对应相同对象,这也是什么用mybatis的时候,语句可以不写namespace的原因。具体解析以后再分析。

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

内部类MethodSignature定义了接口中方法的各种信息。

[图片上传失败...(image-97b844-1542177065562)]

至此MapperMethod对象完成创建。接下来调用execute方法。

[图片上传失败...(image-e84502-1542177065562)]

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

你可能感兴趣的:(Mybatis面向接口编程实践与mapper代理对象生成)