浅析mybatis源码(三)Mapper

这篇主要看下mybatis的Mapper,Mapper可以说是mybatis的入口。这里仅讨论注解的方式。
回顾下第一篇中mybatis是如何使用的。

sqlSession = SqlSessionFactoryUtil.getSqlSession();
productMapper = sqlSession.getMapper(ProductMapper.class);
Product product = productMapper.detail(1);

可以看到获取Session后(第二篇讲到了,本质就是获取到一个数据库连接),获取productMapper,ProductMapper是我们定义的一个接口,detail是我们定义的一个抽象方法。 接口并没有实现方法,因此可以猜想到mybatis帮我们生成了一个实现了ProductMapper接口的类。

思路

那可以试想下,让我们自己实现这个类,是怎样的流程呢?
首先,getMapper有个入参是ProductMapper.class。也就是我们有ProductMapper这个接口,接口上每个方法中的注解上都定义了该如何执行sql。通过反射能够拿到这些sql信息生成类则可以使用动态代理,因为ProductMapper是接口,我们可以用jdk动态代理。

mybatis生成productMapper流程

mybatis生成productMapper是分两步的,第一步是在初始化的时候addMapper,第二步则是在使用的时候getMapper。为什么要这样做呢,因为解析注解、生成工厂类等都是重复的工作。可以在初始化前计算好。使用的时候拿来用就行了。

getMapper流程
  public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
    final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
    if (mapperProxyFactory == null) {
      throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
    }
    try {
      return mapperProxyFactory.newInstance(sqlSession);
    } catch (Exception e) {
      throw new BindingException("Error getting mapper instance. Cause: " + e, e);
    }
  }

getMapper的流程比较简单,就是通过Mapper在knownMappers(addMapper中会讲)中取到对应的Mapper代理工厂。然后通过工厂构建Mapper代理。

addMapper流程


可以看到最终一共生成了三份重要数据,类型分别为Mapper代理工厂类,ResultMap,MappedStatement类。都保存在了Map结构中。
knowMappers保存在了configuration.mapperRegistry中。键是Mapper.class,值是对应的Mapper代理工厂。
resultMaps保存在了configuration中。键是个字符串,这样拼接的"${Mapper包路径}.${Mapper类名}.${执行方法名}.${方法返回类型}",值是这个方法对应的结果处理配置。
mappedStatments保存在了configuration中。键是个字符串,这样拼接的"${Mapper包路径}.${Mapper类名}.${执行方法名}",值是这个方法对应的sql执行配置。
那这些数据什么时候使用呢?
在getMapper的时候,便可以取出来Mapper工厂来生成Mapper类。
当执行Mapper中某个方法时,便可以从MappedStatement中找到执行的sql数据,得到结果后,可以从ResultMap中找到定义的结果类型,将结果转为定义的类型

后面三篇文章会分别从这三个类出发来进行讨论。

转载于:https://my.oschina.net/u/3361610/blog/3012573

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值