寫在之前
最近在使用Mybatis的時候很是好奇一些實現(xiàn)細節(jié)竭业,所以也就多留意了下智润。 SqlSessionFactory、SqlSessionFactoryBean未辆、SqlSession和SqlSessionTemplate是大家直接使用比較多的窟绷。這里我先不說這些類的實現(xiàn)細節(jié),先大致說下它們之間的關(guān)系咐柜,相信會有同樣的人對于它們之間的關(guān)系感興趣兼蜈。設(shè)計者設(shè)計這個類的時候肯定是有目的性的,搞清楚目的性再去看實現(xiàn)源碼才會有方向性拙友,從而達到事半功倍的效果为狸。我會結(jié)合自己的理解,連續(xù)通過幾篇文章來講述下它們之間的感情糾葛遗契,并結(jié)合生成環(huán)境中的常用方式進行實例說明辐棒。若是您發(fā)現(xiàn)文章有錯誤的地方,還望不惜筆墨牍蜂,吾當虛心接受漾根,感激涕零。
正文
1. SqlSession和SqlSessionTemplate
SqlSession實現(xiàn)了Closeable接口鲫竞,代表SqlSession是可以關(guān)閉的辐怕,那也就是說SqlSession代表一種可關(guān)閉的連接,也正如名字所表達的是Session从绘,Session對于開發(fā)人員來說并不陌生寄疏。例如:瀏覽器和服務(wù)器之間的會話也是Session,Session用來維護無狀態(tài)請求之間的狀態(tài)的信息僵井。所以說SqlSession也是一種會話赁还,數(shù)據(jù)庫連接客戶端和數(shù)據(jù)庫Server之間的一種會話,并維護了客戶端和數(shù)據(jù)庫Server的一些狀態(tài)信息驹沿。
看源碼中的描述:
SqlSession是接口,接口是一種高層次的抽象蹈胡,你可以認為接口是聲明了一種能力渊季。朋蔫。若是實現(xiàn)了該接口,就擁有了該接口的能力(方法)和特征(屬性)却汉。官方的描述是:“你可以通過它執(zhí)行命令驯妄、獲取mapper和管理事務(wù)”。那也就是說合砂,只要我實現(xiàn)了SqlSession接口青扔,那我就有了同樣的能力了。至于它是如何實現(xiàn)發(fā)送sql語句翩伪,管理事務(wù)和獲取mapper的微猖,這是后話,后續(xù)再說缘屹。
我們再來看看凛剥,實現(xiàn)了SqlSession的類有哪些?
正如圖中所示轻姿,DefaultSqlSession是SqlSession接口的默認實現(xiàn)犁珠;SqlSessionTemplate也是SqlSession的一種實現(xiàn)。SqlSessionTemplate除了實現(xiàn)了SqlSession接口外互亮,還是實現(xiàn)了下面的接口:
實現(xiàn)了DisposableBean接口犁享,也就代表了SqlSessionTemplate的實例被Bean工廠發(fā)現(xiàn)后,會把它們納入整個生命周期的管理過程中豹休,當BeanFactory被嘗試銷毀時炊昆,Beans的管理者會以回調(diào)的方式調(diào)用SqlSessionTemplate的destroy()方法。 我們來看看SqlSessionTemplate的destroy()方法的實現(xiàn):
默認實現(xiàn)是空方法慕爬,具體實現(xiàn)你自己可以重寫窑眯。
2. SqlSessionFactory和SqlSessionFactoryBean
如上圖,SqlSessionFactory也是一種抽象定義医窿,其能力(方法 )就是打開一個會話(客戶端和數(shù)據(jù)庫Server)磅甩,而且重載了很多不同的參數(shù),你可以改變這些參數(shù)自定義會話過程中的一些默認行為姥卢。例如:可以設(shè)置自動提交事務(wù)或是關(guān)閉自動提交卷要;可以設(shè)置獲取數(shù)據(jù)庫連接的線程的類型(重用,每次新產(chǎn)生等等)独榴;也可以獲取整個Mybatis的配置信息的Configuration對象實例僧叉,關(guān)于Configuration的討論我們下期再說。
SqlSessionFactory的實現(xiàn)也有兩種棺榔,甚至你可以自定義實現(xiàn)瓶堕。默認實現(xiàn)是DefaultSqlSessionFactory
DefaultSqlSessionFactory具體實現(xiàn)了SqlSessionFactory接口定義的抽象行為≈⑿總而言之郎笆,SqlSessionFactory就是生產(chǎn)SqlSession對象的工廠谭梗。那也就是說整個Mybatis中,如果只有一個數(shù)據(jù)庫Server要連接宛蚓,那么只需要一個工廠就夠了(只有一個SqlSessionFactory的實例對象)激捏,而SqlSession可以自由的被關(guān)閉,也就代表SqlSession是需要反復(fù)被創(chuàng)建的凄吏。上面說到SqlSession是關(guān)聯(lián)到具體數(shù)據(jù)庫連接的远舅,但是如果每次創(chuàng)建和銷毀都直接操作物理連接的話,那么這個資源浪費很高痕钢,效率很低图柏。請看DefaultSqlSessionFactory的方法:
上圖的實現(xiàn)中是有基于連接池技術(shù)的。使用數(shù)據(jù)庫連接池時盖喷,關(guān)閉SqlSession實例 爆办,其實只是把數(shù)據(jù)庫連接對象(代表物理資源)放回到對象池中,并沒有直接銷毀课梳,使用連接池技術(shù)極大提高了物理資源利用率距辆,縮減了創(chuàng)建物理連接所需的時間、資源等等暮刃。
如上圖跨算,SqlSessionFactoryBean直接實現(xiàn)了三個接口。實現(xiàn)ApplicationListener代表SqlSessionFactoryBean有能力監(jiān)控 Application發(fā)出的一些事件通知椭懊;實現(xiàn)InitializingBean代表SqlSessionFactoryBean中的afterPropertiesSet()方法會在Bean初始化屬性完成后立即被調(diào)用诸蚕;實現(xiàn)了FactoryBean代表SqlSessionFactoryBean的實例不再是普通的Bean對象,而是可以產(chǎn)生自己Bean的一種工廠氧猬,該工廠產(chǎn)生的Bean同樣可以被納入Spring的生命周期背犯。
正如SqlSessionFactoryBean的名字,它是生產(chǎn)SqlSessionFactory的工廠Bean盅抚。
綜上所述漠魏,SqlSessionFactoryBean是生產(chǎn)SqlSessionFactory的一種工廠Bean;SqlSessionFactory是一種生產(chǎn)SqlSession的工廠妄均;SqlSession是代表數(shù)據(jù)庫連接客戶端和數(shù)據(jù)庫Server之間的會話信息柱锹;SqlSessionTemplate是SqlSession的一個具體實現(xiàn)。如下圖:
說明:圖中的藍色箭頭不代表繼承的含義丰包。
寫在最后
看完上面的大致講述后禁熏,你會不會有些問題要問呢?比如:既然SqlSessionFactory是產(chǎn)生SqlSession的了邑彪,那干嘛又搞出來SqlSessionTemplate呢瞧毙?它到底是干嘛的呢?說到SqlSessionTemplate和SqlSession、SqlSessionFactory之間的糾纏宙彪,就不得不說動態(tài)代理了撑柔。下期我們將講述SqlSessionTemplate的實現(xiàn)細節(jié),我們的代碼中是如何產(chǎn)生Sql語句并發(fā)送給數(shù)據(jù)庫Server的您访,通過進一步的分析讓你更加了解Mybatis的實現(xiàn)細節(jié)末梢。預(yù)知后事如何剪决,且看下回分解灵汪。