MyBatis源码分析篇----org.apache.ibatis.session.SqlSession#getMapper的源码分析

源起

  • 上节我们了解了诸如:session.selectOnesession.selectList等方法的源码实现;
  • 比如:我们可以查看mybatis-3.5.4源码测试包中org.apache.ibatis.session.SqlSessionTest#shouldSelectOneAuthor,这个方法:
  • 上图中,框选出的statement是以硬编码的方式存在在代码中的,对于后台人员来讲,这部分的编码是不易维护的,所以,MyBatis封装了Mapper,通过初始化加载,将所有的Mapper文件与SQL文件建立一一对应关系,而在调用的时候使用API调用方式,直接调用。
  • 所以我们可以首先获取到Mapper映射器,然后调用其方法执行查询即可,这也是我们最常用的方式;可参考源码包中测试方法org.apache.ibatis.session.SqlSessionTest#shouldSelectAuthorsUsingMapperClass

源码分析

  • 首先我们需要获取到SqlSession,这个已经在上篇源码分析中已做讲解;需要的可参考
DefaultSqlSession#getMapper
  • 首先调用org.apache.ibatis.session.defaults.DefaultSqlSession#getMapper方法获取一个映射器代理类;(可以理解为使我们写的dao接口,只不过是被代理过的,下面会详细讲到)

  • org.apache.ibatis.session.Configuration中保存了全局配置信息;

MapperRegistry#getMapper
  • protected final MapperRegistry mapperRegistry = new MapperRegistry(this);Configuration的一个属性,它内部维护了一个private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<>();用以存储已经存在的Mapper映射信息;这个操作是在初始化配置信息中就已经加载了,这个我们在之前的源码分析中已分析,可参考:源码分析篇全局配置文件初始化
  • 当我们的程序一启动,这个knownMappers就已经被初始化了,且knownMapperskey=xxx.ClassValue是一个代理类工厂MapperProxyFactory,最后可通过mapperProxyFactory.newInstance(sqlSession)获取代理类MapperProxy,通过这里,我们可以看出,因为用的是代理类,所以我们的Mapper接口不需要实现类
JDK动态代理生成代理类
  • 获取接口代理类的方式采用的是JDK的动态代理生成代理类;
  • mapperProxyFactory.newInstance(sqlSession)获取代理类MapperProxy

MapperProxy#invoke
  • 通过org.apache.ibatis.session.defaults.DefaultSqlSession#getMapper获取到了Mapper的代理类MapperProxy
  • 接下来调用Mapper中定义的方法,则必然执行的是代理类的invoke方法;

  • PlainMethodInvokerMapperProxy的一个静态内部类,cachedInvoker返回PlainMethodInvoker,再调用invoke执行方法

new MapperMethod
  • cachedInvoker方法中new PlainMethodInvoker传递了一个MapperMethodMapperMethod中有两个静态内部类;如下图所示:

  • SqlCommand中维护了SQL的操作命令,包含nameSpace+节点ID值、需要执行SQL的类型(INSERT|DELETE|UPDATE|SELECT
  • MethodSignature维护方法签名,保存了当前需要执行方法的返回值类型,参数名称解析器等信息;
MapperMethod#execute
  • 综上,我们已经获取到了,SQL执行相关的信息,接下来,我们看下具体的执行;
  • 不论invoke方法中走哪段逻辑,最后都会调用到execute方法中执行
  • 这里不论增删改查哪种方法,最终都会调用到SqlSession中的增删改查方法。
  • 对于SqlSession中的查询方法执行流程,可参考上篇博文;SqlSession#select
时序图

公众号推荐

微信公众号:从demo到折腾源码
微信号:albert_ztym
从demo到手撕源码

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值