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的所有方法
execute方法的執行再次委託給了SqlSessionTemplate來執行–sqlSession的接口方法,都被靜態代理使用了SqlSessionTemplate.sqlSession成員(即SqlSessionInterceptor)來調用。
後邊補充下MapperMethod類的說明!!!
SqlSessionTemplate的內部類SqlSessionInterceptor攔截dao的方法,再次獲取SqlSession,
這個時候的SqlSession這個時候的SqlSession是每次dao請求都會創建的,
跟上面的SqlSessionTemplate的成員SqlSession代理在啓動的時候和Dao綁定的只有一次,區分開!!!
我們debug一個dao的請求棧dao.batchQueryByIds(List< Long> ids)
你就把Object result = method.invoke(sqlSession,args)–>dao.findById(Long id);
這要是不懂的話沒意思了趕緊補下基本功,動態代理!!
正如我們所說的,dao.batchQueryByIds(List)進入到SqlSessionInterceptor.invoke方法。
方法getSqlSession(sqlSessionFactory,ExecutorType,ExceptionTranslator);是DefaultSqlSession獲取
看上面的調用棧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,在Spring環境下使用的SpringTransactionFactory
既然有多個工廠,我們怎麼設置使用指定的工廠?
手動指定 < transactionManager type=”JDBC” />
TransactionFactory
TransactionFactory當然就是創建Transaction
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