參考
MyBatis官方中文文檔
MyBatis官方寫的各種語(yǔ)言的文檔古戴,重點(diǎn)資料。
1. 對(duì)于SqlSessionFactoryBuilder矩肩、SqlSessionFactory和SqlSession的作用域(Scope)和生命周期
1.1 使用依賴注入框架(如spring)
依賴注入框架可以創(chuàng)建線程安全的现恼、基于事務(wù)的 SqlSession 和映射器(mapper)并將它們直接注入到你的 bean 中,因此可以直接忽略它們的生命周期黍檩。
總結(jié):使用spring等依賴注入框架叉袍,自己不用去管其生命周期。
1.2 SqlSessionFactoryBuilder
這個(gè)類可以被實(shí)例化刽酱、使用和丟棄喳逛,一旦創(chuàng)建了 SqlSessionFactory,就不再需要它了棵里。因此 SqlSessionFactoryBuilder 實(shí)例的最佳作用域是方法作用域(也就是局部方法變量)润文。你可以重用 SqlSessionFactoryBuilder 來創(chuàng)建多個(gè) SqlSessionFactory 實(shí)例,但是最好還是不要讓其一直存在以保證所有的 XML 解析資源開放給更重要的事情殿怜。
總結(jié):SqlSessionFactoryBuilder典蝌,方法作用域,用完即丟棄头谜。
1.3 SqlSessionFactory
SqlSessionFactory 一旦被創(chuàng)建就應(yīng)該在應(yīng)用的運(yùn)行期間一直存在赠法,沒有任何理由對(duì)它進(jìn)行清除或重建。使用 SqlSessionFactory 的最佳實(shí)踐是在應(yīng)用運(yùn)行期間不要重復(fù)創(chuàng)建多次,多次重建 SqlSessionFactory 被視為一種代碼“壞味道(bad smell)”砖织。因此 SqlSessionFactory 的最佳作用域是應(yīng)用作用域款侵。有很多方法可以做到,最簡(jiǎn)單的就是使用單例模式或者靜態(tài)單例模式侧纯。
總結(jié):SqlSessionFactory新锈,應(yīng)用作用域,全局只要一個(gè)眶熬,使用單例模式妹笆。
1.4 SqlSession
每個(gè)線程都應(yīng)該有它自己的 SqlSession 實(shí)例。SqlSession 的實(shí)例不是線程安全的娜氏,因此是不能被共享的拳缠,所以它的最佳的作用域是請(qǐng)求或方法作用域。絕對(duì)不能將 SqlSession 實(shí)例的引用放在一個(gè)類的靜態(tài)域贸弥,甚至一個(gè)類的實(shí)例變量也不行窟坐。也絕不能將 SqlSession 實(shí)例的引用放在任何類型的管理作用域中,比如 Servlet 架構(gòu)中的 HttpSession绵疲。如果你現(xiàn)在正在使用一種 Web 框架哲鸳,要考慮 SqlSession 放在一個(gè)和 HTTP 請(qǐng)求對(duì)象相似的作用域中。換句話說盔憨,每次收到的 HTTP 請(qǐng)求徙菠,就可以打開一個(gè) SqlSession,返回一個(gè)響應(yīng)郁岩,就關(guān)閉它婿奔。這個(gè)關(guān)閉操作是很重要的,你應(yīng)該把這個(gè)關(guān)閉操作放到 finally 塊中以確保每次都能執(zhí)行關(guān)閉问慎。
下面的示例就是一個(gè)確保 SqlSession 關(guān)閉的標(biāo)準(zhǔn)模式:
SqlSession session = sqlSessionFactory.openSession();
try {
// do work
} finally {
session.close();
}
在你的所有的代碼中一致性地使用這種模式來保證所有數(shù)據(jù)庫(kù)資源都能被正確地關(guān)閉萍摊。
總結(jié):
- SqlSession不是線程安全的,也就是說蝴乔,多線程使用時(shí)要注意,SqlSession不能共享驮樊;
- 所以薇正,SqlSession的最佳作用域?yàn)檎?qǐng)求或方法作用域;
- 所以囚衔,嚴(yán)禁將SqlSession實(shí)例的引用放在一個(gè)類的靜態(tài)域挖腰,甚至一個(gè)類的實(shí)例變量也不行。
1.5 映射器實(shí)例(Mapper Instances)
映射器是一個(gè)你創(chuàng)建來綁定你映射的語(yǔ)句的接口练湿。映射器接口的實(shí)例是從 SqlSession 中獲得的猴仑。因此從技術(shù)層面講,任何映射器實(shí)例的最大作用域是和請(qǐng)求它們的 SqlSession 相同的。盡管如此辽俗,映射器實(shí)例的最佳作用域是方法作用域疾渣。也就是說,映射器實(shí)例應(yīng)該在調(diào)用它們的方法中被請(qǐng)求崖飘,用過之后即可廢棄荸频。并不需要顯式地關(guān)閉映射器實(shí)例宜鸯,盡管在整個(gè)請(qǐng)求作用域(request scope)保持映射器實(shí)例也不會(huì)有什么問題,但是很快你會(huì)發(fā)現(xiàn),像 SqlSession 一樣褒繁,在這個(gè)作用域上管理太多的資源的話會(huì)難于控制。所以要保持簡(jiǎn)單堤尾,最好把映射器放在方法作用域(method scope)內(nèi)服赎。下面的示例就展示了這個(gè)實(shí)踐:
SqlSession session = sqlSessionFactory.openSession();
try {
BlogMapper mapper = session.getMapper(BlogMapper.class);
// do work
} finally {
session.close();
}
總結(jié):方法作用域
1.6 小結(jié)
總結(jié):
- SqlSessionFactory使用單例模式,全局唯一梁沧;
- SqlSession即用即創(chuàng)建檀何,用完要關(guān)閉。