Mybatis 代理模式

1. 代理方式获取Mapper -> getMapper()

Mybatis 代理模式_第1张图片
思考一个问题,通常的Mapper接口我们都没有实现的方法却可以使用,是为什么呢?答案很简单动态代理。
开始之前介绍一下MyBatis初始化时对接口的处理:MapperRegistry是Configuration中的一个属性,它内部维护一个HashMap用于存放mapper接口的工厂类,每个接口对应一个工厂类。mappers中可以
配置接口的包路径,或者某个具体的接口类。
Mybatis 代理模式_第2张图片
当解析mappers标签时,它会判断解析到的是mapper配置文件时,会再将对应配置文件中的增删改查标签 封装成MappedStatement对象,存入mappedStatements中。(上文介绍了)当判断解析到接口时,会建此接口对应的MapperProxyFactory对象,存入HashMap中,key =接口的字节码对象,value =此接口对应的MapperProxyFactory对象。
下面去看一下getMapper方法的实现过程。
首先是DefaultSqlSession中的getMapper
Mybatis 代理模式_第3张图片
可以看到调用的是Configuration中的getMapper
Mybatis 代理模式_第4张图片
这里我们看到了mapperRegistry对象,这个也就是在初始化过程中将
Mapper的代理对象存储的位置。接着我们进到mapperRegistry.getMapper方法中:
Mybatis 代理模式_第5张图片
mapperRegistry.newInstance方法
Mybatis 代理模式_第6张图片
到这里我们也就能理解了,在初始化过程中,将配置文件中配置的mapper对应的接口创建一个代理对象存到Configuration对象的mapperRegistry对象中,将mapper的class全路径限定名称作为Key,将代理对象作为value存到一个mapper中。调用getMapper方法是直接根据Key就能获取代理对象了。

2. invoke方法执行

在动态代理返回了示例后,我们就可以直接调用mapper类中的方法了,但代理对象调用方法,执行是在MapperProxy中的invoke方法中。
Mybatis 代理模式_第7张图片
进入execute方法:
Mybatis 代理模式_第8张图片
可以看到这里定义了很多操作的类型insert/select/update/delete,就拿select方法来说:
Mybatis 代理模式_第9张图片
Mybatis 代理模式_第10张图片
进入sqlSession.select方法,
Mybatis 代理模式_第11张图片
发现最终还是有executor来执行query方法来执行操作,这个跟传统的方式就没有什么区别了。

你可能感兴趣的:(Mybatis,数据库架构)