SqlSessionFactory、SqlSessionFactoryBean、SqlSession和SqlSessionTemplate的不解姻緣系列之一(總體闡述)


摘自:https://www.jianshu.com/p/f19a58938959

寫在之前

最近在使用Mybatis的時候很是好奇一些實現細節,所以也就多留意了下。 SqlSessionFactory、SqlSessionFactoryBean、SqlSession和SqlSessionTemplate是大家直接使用比較多的。這里我先不說這些類的實現細節,先大致說下它們之間的關系,相信會有同樣的人對於它們之間的關系感興趣。設計者設計這個類的時候肯定是有目的性的,搞清楚目的性再去看實現源碼才會有方向性,從而達到事半功倍的效果。我會結合自己的理解,連續通過幾篇文章來講述下它們之間的感情糾葛,並結合生成環境中的常用方式進行實例說明。若是您發現文章有錯誤的地方,還望不惜筆墨,吾當虛心接受,感激涕零。

正文

1. SqlSession和SqlSessionTemplate

 
SqlSession

SqlSession實現了Closeable接口,代表SqlSession是可以關閉的,那也就是說SqlSession代表一種可關閉的連接,也正如名字所表達的是Session,Session對於開發人員來說並不陌生。例如:瀏覽器和服務器之間的會話也是Session,Session用來維護無狀態請求之間的狀態的信息。所以說SqlSession也是一種會話,數據庫連接客戶端和數據庫Server之間的一種會話,並維護了客戶端和數據庫Server的一些狀態信息。

看源碼中的描述:

 
SqlSession

SqlSession是接口,接口是一種高層次的抽象,你可以認為接口是聲明了一種能力。。若是實現了該接口,就擁有了該接口的能力(方法)和特征(屬性)。官方的描述是:“你可以通過它執行命令、獲取mapper和管理事務”。那也就是說,只要我實現了SqlSession接口,那我就有了同樣的能力了。至於它是如何實現發送sql語句,管理事務和獲取mapper的,這是后話,后續再說。

我們再來看看,實現了SqlSession的類有哪些?

 
SqlSession的實現類

正如圖中所示,DefaultSqlSession是SqlSession接口的默認實現;SqlSessionTemplate也是SqlSession的一種實現。SqlSessionTemplate除了實現了SqlSession接口外,還是實現了下面的接口:

 
SqlSessionTemplate

實現了DisposableBean接口,也就代表了SqlSessionTemplate的實例被Bean工廠發現后,會把它們納入整個生命周期的管理過程中,當BeanFactory被嘗試銷毀時,Beans的管理者會以回調的方式調用SqlSessionTemplate的destroy()方法。 我們來看看SqlSessionTemplate的destroy()方法的實現:

 
destroy()方法

默認實現是空方法,具體實現你自己可以重寫。

2. SqlSessionFactory和SqlSessionFactoryBean

 
SqlSessionFactory

如上圖,SqlSessionFactory也是一種抽象定義,其能力(方法 )就是打開一個會話(客戶端和數據庫Server),而且重載了很多不同的參數,你可以改變這些參數自定義會話過程中的一些默認行為。例如:可以設置自動提交事務或是關閉自動提交;可以設置獲取數據庫連接的線程的類型(重用,每次新產生等等);也可以獲取整個Mybatis的配置信息的Configuration對象實例,關於Configuration的討論我們下期再說。

 
SqlSessionFactory的實現

SqlSessionFactory的實現也有兩種,甚至你可以自定義實現。默認實現是DefaultSqlSessionFactory

 
DefaultSqlSessionFactory

DefaultSqlSessionFactory具體實現了SqlSessionFactory接口定義的抽象行為。總而言之,SqlSessionFactory就是生產SqlSession對象的工廠。那也就是說整個Mybatis中,如果只有一個數據庫Server要連接,那么只需要一個工廠就夠了(只有一個SqlSessionFactory的實例對象),而SqlSession可以自由的被關閉,也就代表SqlSession是需要反復被創建的。上面說到SqlSession是關聯到具體數據庫連接的,但是如果每次創建和銷毀都直接操作物理連接的話,那么這個資源浪費很高,效率很低。請看DefaultSqlSessionFactory的方法:

 
DefaultSqlSessionFactory的方法

上圖的實現中是有基於連接池技術的。使用數據庫連接池時,關閉SqlSession實例 ,其實只是把數據庫連接對象(代表物理資源)放回到對象池中,並沒有直接銷毀,使用連接池技術極大提高了物理資源利用率,縮減了創建物理連接所需的時間、資源等等。

 
SqlSessionFactoryBean

如上圖,SqlSessionFactoryBean直接實現了三個接口。實現ApplicationListener代表SqlSessionFactoryBean有能力監控 Application發出的一些事件通知;實現InitializingBean代表SqlSessionFactoryBean中的afterPropertiesSet()方法會在Bean初始化屬性完成后立即被調用;實現了FactoryBean代表SqlSessionFactoryBean的實例不再是普通的Bean對象,而是可以產生自己Bean的一種工廠,該工廠產生的Bean同樣可以被納入Spring的生命周期。

 
FactoryBean的官方描述

正如SqlSessionFactoryBean的名字,它是生產SqlSessionFactory的工廠Bean。

綜上所述,SqlSessionFactoryBean是生產SqlSessionFactory的一種工廠Bean;SqlSessionFactory是一種生產SqlSession的工廠;SqlSession是代表數據庫連接客戶端和數據庫Server之間的會話信息;SqlSessionTemplate是SqlSession的一個具體實現。如下圖:

 
關系圖

說明:圖中的藍色箭頭不代表繼承的含義。

寫在最后

看完上面的大致講述后,你會不會有些問題要問呢?比如:既然SqlSessionFactory是產生SqlSession的了,那干嘛又搞出來SqlSessionTemplate呢?它到底是干嘛的呢?說到SqlSessionTemplate和SqlSession、SqlSessionFactory之間的糾纏,就不得不說動態代理了。下期我們將講述SqlSessionTemplate的實現細節,我們的代碼中是如何產生Sql語句並發送給數據庫Server的,通過進一步的分析讓你更加了解Mybatis的實現細節末梢。預知后事如何,且看下回分解。



作者:大道至簡_Andy
鏈接:https://www.jianshu.com/p/f19a58938959
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。


免責聲明!

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



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