通俗易懂理清mybatis中SqlSession、SqlSessionTemplate、SessionFactory和SqlSessionFactoryBean之間的關係

公衆號:灰太狼學爪哇。(一個java程序員都在關注的公衆號)

前言

先容我哭一會兒,嗚嗚嗚~昨晚寫了一半的文章,還沒保存就蓋上蓋子準備回家,拔下電源準備把電腦塞進書包帶回家完成時,懶惰阻止了我,最終還是沒帶回家,於是,遭報應了,今天早上來,電腦直接就是沒電關機了,開機後寫的文章再也找不回來了…(不爭氣的mac真是對不起我前面特地寫了一篇文章來誇讚mac真香啊…)

Thread.sleep(5000);//crying…

迴歸正題,開始含淚創作了。

很多初學者在學習mabatis或者看公司的mybatis項目時,總是搞不清楚SqlSessionSql、SqlSessionTemplate、SessionFactory和SqlSessionFactoryBean這幾者之間的關係,尤其是我們在看別人的代碼時,不同的項目都是不同的人完成的,風格迥異,有人用spring配置的形式,有人用springboot硬編碼的形式,更有複雜點的項目,使用了讀寫分離等等,很容易讓人懵圈。這篇文章的目的就是用通俗易懂的方式給大家理清這幾者之間的關係。如若您發現文章某些部分難以理解,或者有錯誤,還望不惜筆墨,吾當虛心接受,感激涕零。如若您覺得有幫助,點個贊支持下,感謝感謝~

來,打起精神來。

正文

SqlSession和SqlSessionTemplate

首先給大家帶來的是SqlSession和SqlSessionTemplate之間的關係,先看圖,再看描述。

SqlSession實現了Closeable接口,代表SqlSession是可以關閉的,那也就是說SqlSession代表一種可關閉的連接。正如他的名字,session表示的是一個會話,用來維護無狀態請求之間的狀態信息,放在數據庫這裏,SqlSession表示的是數據庫客戶端和數據庫服務端之間的一種會話,並維護了兩者之間的狀態信息。

我們看到,SqlSession是一個接口,裏面有我們熟悉的操作數據庫執行sql語句的select、insert、update等方法,是不是很熟悉。

SqlSession有三個實現類,當然,你也可以自己實現。DefaultSqlSession是它的默認實現類,當然,還有我們熟悉的SqlSessionTemplate實現類。小夥伴們是不是已經打開代碼開始看了,如果還沒有,我建議你打開源碼,跟着我的思路往下走。

聰明的你是不是早就已經發現了,DefaultSqlSession和SqlSessionTemplate差別很大,但是咱們這次討論的重點是SqlSessionTemplate,就不展開講述他們之間的區別了,其實如果你能認真看到最後,你就自然就清楚區別了。

值得一提的是,SqlSessionTemplate除了實現了Sqlsession接口之外,還實現了DisposableBean接口,這就意味着,SqlSessionTemplate的實例被Bean工廠發現後,會把他們納入整個spring bean生命週期的管理過程之中,當BeanFactory嘗試銷燬時,Beans的管理者會以回調的方式調用SqlSessionTemplate的destroy()方法。

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

總結一下,SqlSessionTemplate是SqlSession的實現類,如其名,是sqlSession模板,有了SqlSessionTemplate,我們就能用來執行Dao層的Sql語句。說了這麼多,其實關鍵就一點,SqlSessionTmplate是SqlSession的實現類,而這個實現類中有一個關鍵的類就是SqlSessionFactory。

SqlSessionFactory和SqlSessionFactoryBean

SqlSessionFactory也是一個接口,是SqlSession工廠,他的能力就是打開一個SqlSession會話,而且重載了許多不同的參數,你可以改變這些參數自定義會話過程中的一些默認行爲。例如:可以設置自動提交事務或是關閉自動提交;可以設置獲取數據庫連接的線程的類型(重用,每次新產生等等);也可以獲取整個Mybatis的配置信息的Configuration對象實例等等。

SqlSessionFactory默認也有兩個實現類,當然你也可以自定義實現類。默認實現是DefaultSqlSessionFactory。

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

上圖是基於數據庫連接池實現的,也就是說一次連接用完關閉SqlSession實例時,只是把數據庫連接對象放回到對象池中,並沒有直接銷燬,使用池技術,大大提高了物力資源利用率,縮短連接時間、減少了資源利用等。

講到這裏,細心的小夥伴們可能有個疑問,SqlSessionFactory是怎麼創建SqlSession的,或者更具體點,是怎麼創建SqlSessionTemplate的,這就不得不說動態代理了。這部分是在SqlSessionTemplate中實現的,具體細節我下期再從源碼角度給大家分享。

所剩不多了,再堅持堅持,堅持看完。

接下來要說的是SqlSessionFactoryBean,老規律,類圖如下:

實現了ApplicationListener接口,代表SqlSessionFactoryBean有能力監控 Application發出的一些事件通知。

實現了FactoryBean接口,代表SqlSessionFactoryBean的實例不再是一個普通的bean對象,而是可以產生自己Bean的一個工廠,並且產生的Bean會被納入spring的生命週期,這裏產生的Bean指的就是SqlSessionFactory。

實現了InitializingBean接口,代表SqlSessionFactoryBean中的afterPropertiesSet()方法會在Bean初始化屬性完成後立即被調用。

如其名,SqlSessionFactoryBean是生產SqlSessionFactory的工廠bean。

綜上所述

SqlSessionFactoryBean是生產SqlSessionFactory的一種工廠bean。

SqlSessionFactory是打開SqlSession會話的工廠,是一個接口,可以根據需求自己實現,它的默認實現類DefaultSqlSessionFactory使用了數據庫連接池技術。

SqlSession是客戶端和數據庫服務端之間的會話信息,裏面有許多操作數據庫的方法。

SqlSessionTemplate是SqlSession的一個具體實現。

寫在最後

寫到這裏,不知道小夥伴們是否已經搞清楚他們之間的關係了呢。上面講的其實比較淺顯,主要是從結構上給大家梳理了下他們之間的關係,以及它們每一個的作用,但是這還遠遠不夠,就像上面提到的,SqlSessionTemplate和SqlSession、SqlSessionFactory之間的糾纏到底是怎麼樣的?DataSource、Connection是怎麼發揮作用的?以及我們的代碼中是如何產生Sql語句併發送給數據庫Server的?

我是灰太狼,一個95後自我精進的java程序員。個人運營的公衆號:灰太狼學爪哇。你想知道的都在這裏。(關注免費領取100G各階段的學習、面試資料)

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