Mybatis源码(二)之Spring整合mybatis创建SqlSession

Spring未整合Mybatis和整合之后Mybatis获取的方式:

Spring没有整合Mybatis之前,获取SqlSession很简单就是

DefaultSqlSessionFactory.openSession();

Spring整合Mybatis的时候,稍复杂些:
扫描dao,注册BeanDefinition并setBeanClass=MapperFactoryBean

SqlSessionTemplate 实现了SqlSession
SqlSessionTemplate 有成员SqlSession sqlSessionProxy;
这两步包含了动态代理和静态代理 自己意会下!!!!

容器启动时
Spring调用MapperFactoryBean.getObject()来生成Dao代理MapperyProxy分成如下两步:

1、this.getSqlsession()其实返回的SqlSessionTemplate,也是SqlSession,
同时也生成了SqlSession的代理类SqlSessinonInterceptor赋值给成员

2、sqlSessionTemplate.getMapper(daoInterface);SqlSessionTemplate有Configuration对象。
Configuration.getMapper(daoInterface,sqlsessionTemplate);
new MapperProxy(sqlSessionTemplate,daoInterface)是个代理类;
这样一来dao就是MapperProxy,MapperProxy中包含SqlSessionTemplate,sqlSessionTemplate成员是另一个代理类SqlSessionInterceptor。

dao调用时

再次之前先看下我这篇博文,原生jdbc操作数据库 提交回滚,事务代码样例

当dao被调用时MapperProxy的方法被触发,proxy缓存该dao的所有方法
MapperProxy

execute方法的执行再次委托给了SqlSessionTemplate来执行–sqlSession的接口方法,都被静态代理使用了SqlSessionTemplate.sqlSession成员(即SqlSessionInterceptor)来调用。

后边补充下MapperMethod类的说明!!!

SqlSessionTemplate的内部类SqlSessionInterceptor拦截dao的方法,再次获取SqlSession,

这个时候的SqlSession这个时候的SqlSession是每次dao请求都会创建的,
跟上面的SqlSessionTemplate的成员SqlSession代理在启动的时候和Dao绑定的只有一次,区分开!!!

我们debug一个dao的请求栈dao.batchQueryByIds(List< Long> ids)

sqlSessionTemplate.SqlSessionInterceptor.invoke

你就把Object result = method.invoke(sqlSession,args)–>dao.findById(Long id);
这要是不懂的话没意思了赶紧补下基本功,动态代理!!

正如我们所说的,dao.batchQueryByIds(List)进入到SqlSessionInterceptor.invoke方法。
方法getSqlSession(sqlSessionFactory,ExecutorType,ExceptionTranslator);是DefaultSqlSession获取

DefaultSqlSessionFactory.openSession.openSessionFromDataSource

看上面的调用栈SqlSessionInterceptor.invoke–>
SqlSessionUtil.openSession(SqlSessionFactory,ExecutorType,xxx)–>
DefaultSqlSessionFactory.openFromDataSource(ExecutorType,null,false)
new DefaultSqlSession();

总结:

dao即MapperProxy进入到invoke方法
创建MapperMethod对象,执行execute(sqlSessiontemplate,args)方法
SqlSessionTemplate的内部类静态代理到成员SqlSession动态代理的SqlSessionInterceptor上,拦截dao方法进入invoke方法,进入到getSqlSession,最终返回DefaultSqlSession对象!

在创建SqlSession的时有几个比较重要的对象也被创建了,下面是补充!

Transaction

Transaction接口

三个好基友,抽象工厂分别创建对应的Transaction,在Spring环境下使用的SpringTransactionFactory
既然有多个工厂,我们怎么设置使用指定的工厂?

手动指定 < transactionManager type=”JDBC” />

TransactionFactory
TransactionFactory当然就是创建Transaction

TransactionFactory

Executor

Executor

没有配置默认是SimpleType–常见默认的SimpleExecutor

我们怎才能修改默认的配置呢?

MapperMethod
在MapperProxy中创建执行的execute方法的入口
这里写图片描述

这里写图片描述

这里写图片描述

此时的SqlSession已经有了几个装备的利器!
设置了Configuration对象(所有的配置都可以获取到)
Executor
Executor有了Transaction
Transaction有了DataSource
DataSource有了Connection

method.invoke(SqlSession,args);已放行执行sqlSession.selectList

还需明确几个问题?Connection还会没有看到从哪里取出来,在哪里提交,在哪里回滚,参数怎么组装映射到指定Sql等!再回头看下Mybatis源码之温故jdbc

猜你喜欢

转载自blog.csdn.net/mayongzhan_csdn/article/details/78481987