3.3 获取Mapper对象

3.3 获取Mapper对象,第1张

有一个 DefaultSqlSession 之后, 还要找到 Mapper.xml 里面定义的 Statement ID,才能执行对应的 SQL 语句。

找到 Statement ID 有两种方式:

由于接口名称跟 Mapper.xml 的 namespace 是对应的, 接口的方法跟 statement ID 也都是对应的,所以根据方法名就能找到对应的要执行的 SQL。

DefaultSqlSession.getMapper() 调用了 Configuration.getMapper() 。 Configuration.getMapper() 又调用了 MapperRegistry.getMapper()

在解析 mapper 标签和 Mapper.xml 的时候,已经把接口类型和类型对应的 MapperProxyFactory 放到了一个 Map 中。 获取 Mapper 代理对象, 实际上是从 Map 中获取对应的工厂类后,调用以下方法创建对象:

最终通过代理模式返回代理对象:

JDK 动态代理代理,在实现了 InvocationHandler 的代理类里面,需要传入一个被 代理对象的实现类。

MyBatis 的动态代理不需要实现类的原因:我们只需要根据接口类型+方法的名称, 就可以找到 Statement ID 了,而唯一要做的一件事情也是这件,所以 不需要实现类 。在 MapperProxy 里面直接执行逻辑(也就是执行 SQL)就可以。

获得 Mapper 对象的过程, 实质 上是获取了一个 MapperProxy 的代理对象。 MapperProxy 中有 sqlSession、mapperInterface、methodCache。

可以用对应Mapper类,里面的方法名是对应的sql语句的ID名,这个可以去调用;还有一种,就是不用Mapper类,可以直接用xml的文件名.id名获取的方式,这个方式要有像SqlSessionTemplate这样的类,提前定义好方法获取方式,然后调用就可以了

入口:一般会在DAO层配置中,比如下面是我的配置

在这里面,我们配置了id为sqlSessionFactory的bean。那么这也是我们的入口

由此可以看出,id为sqlSessionFactory的bean默认是DefaultSqlSessionFactory。Mybatis的官方推荐,SqlSessionFactory最好是做成单例的,不需要频繁创建。

通过api获取session的方式

那么我们就看DefaultSqlSessionFactory.openSession方法,如下

再看DefaultSqlSession.getMapper方法

这个 configuration 对象是在哪里创建,又是哪里传入的呢?其实是从一开始的 SqlSessionFactoryBean 中创建好后,赋值给 SqlSessionFactoryBuilder 的build的方法参数,一路传到了 DefaultSqlSession 中。也就是说 configuration 是隶属于 DefaultSqlSessionFactory 的,生命周期很长。

那 configuration 究竟有什么呢?

原来,所有的Mapper接口被扫描后,都会被存储在Configuration的mapperRegistry里的Map中。而且 key = Mapper class value = 创建当前Mapper的工厂 。

接着看 configuration.getMapper(..) 方法

那我们知道了 knownMappers.get(type) 返回的是一个创建Mapper的工厂 MapperProxyFactory 。

接下来我们看看 MapperProxyFactory 是如何创建的。直接看 MapperProxyFactory 的 newInstance(SqlSession sqlSession) 方法

可以清楚的看到,通过jdk的动态代理创建了代理类。那么我们需要关注一下,代理类的InvocationHandler做了哪些事情

这里需要注意methodCache这个Map,不是保存在本类里的。看MapperProxy的有参构造传进来的。那么谁创建的MapperProxy呢?上面我们说了是Mapper对应的Mapper工厂MapperProxyFactory。这个对象也是保存在 Configuration 中,生命周期很长。

这就解释了,为什么 官网上推荐,让Mapper的实现类 用后就可以舍弃(做局部变量),但是这样每次都去创建难道不耗时,答案是不耗时,因为核心的 MapperMethod 都已经被缓存起来了。


欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/sjk/9972838.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2023-05-03
下一篇2023-05-03

发表评论

登录后才能评论

评论列表(0条)

    保存