關於Mybatis與Spring整合之后SqlSession與mapper對象之間數量的問題。


1,sqlsession的真實類型和數量

由於使用spring管理bean,當我們在代碼中需要使用這個bean的時候,會首先去容器中找,第一次需要調用MapperFactoryBean的getObject方法獲取一個bean,並保存到容器中。

MapperFactoryBean的getObject方法如下:

 

由於每個MapperFactoryBean對象初始化的時候,都會創建一個sqlSession,代碼在MapperFactoryBean類的父類SqlSessionDaoSupport中,當spring向MapperFactoryBean對象中注入SqlSessionFactory時就創建了SqlSession:

 

【結論1】:一個MapperFactoryBean對象擁有一個sqlSession對象。類型是org.mybatis.spring.SqlSessionTemplate

重要:spring整合mybatis使用的sqlSession類型是org.mybatis.spring.SqlSessionTemplate

那么整合后的mybatis是怎么執行的呢?

首先查看SqlSessionTemplate類可以看到,所有的數據庫執行都被一個動態代理的sqlsession對象代理了。

 

在構造方法中查看該代理對象的構造

使用JDK動態代理,實現InvocationHandler的類是SqlSessionIntercepteor,查看它的invoke方法如下:

 

可以看到,方法開始就直接創建了一個新的sqlsession對象,這個對象就是被代理的對象。

再看getSqlSession方法,它是SqlSessionUtils中的一個靜態方法,如下:

 

第一句話和事務有關,如果它返回空,則直接使用sessionFactory創建一個新的session

【結論】spring整合mybatis后,非事務環境下,每次操作數據庫都使用新的sqlSession對象。因此mybatis的一級緩存無法使用(一級緩存針對同一個sqlsession有效)

下面兩段代碼:

(1)不整合spring,如下代碼的輸出可以看出,使用了一級緩存

 

結果:查詢過程只執行了一次。

 

(2)整合spring,

 

輸出結果如下:

 

兩次的輸出表示沒有使用一級緩存。

2,Mapper接口對應的bean在容器中的數量

通過getObject返回的對象是單利的,從MapperFactoryBean的isSingleton()可以得出

 

【結論二】因此,同一個IOC容器中同一個Mapper接口對應的代理類只有一個

例如系統有一個UserMapper接口對應UserMapper.xml

則如下代碼返回true

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM