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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章