MyBatis 作用域和生命週期

weixin_33896726發表於2017-01-08
理解到目前為止所討論的類的作用域和生命週期是非常重要的。如果使用不當可導致嚴重的併發性問題。

SqlSessionFactoryBuilder
 
這個類可以在任何時候被例項化、使用和銷燬。一旦您創造了SqlSessionFactory 就不需要
再保留它了。所以SqlSessionFactoryBuilder 例項的最好的作用域是方法體內(即一個本地方法
變數)。您能重用SqlSessionFactoryBuilder 建立多個SqlSessionFactory 例項,但最好不要把
時間、資源放在解析XML 檔案上,而是要從中解放出來做最重要事情。

SqlSessionFactory

 
一旦建立,SqlSessionFactory 將會存在於您的應用程式整個執行生命週期中。很少或根本
沒有理由去銷燬它或重新建立它。最佳實踐是不要在一個應用中多次建立SqlSessionFactory。
這樣做會被視為“沒品味”。所是SqlSessionFactory 最好的作用域範圍是一個應用的生命週期
範圍。這可以由多種方式來實現,最簡單的方式是使用Singleton 模式或靜態Singleton 模式。
但這不是被廣泛接受的最佳做法,相反,您可能更願意使用像Google Guice 或Spring 的依賴注
入方式。這些框架允許您創造一個管理器,用於管理SqlSessionFactory 的生命週期。

SqlSession

 
每個執行緒都有一個SqlSession 例項,SqlSession 例項是不被共享的,並且不是執行緒安全
的。因此最好的作用域是request 或者method。決不要用一個靜態欄位或者一個類的例項欄位來
儲存SqlSession 例項引用。也不要用任何一個管理作用域,如Servlet 框架中的HttpSession,
來儲存SqlSession 的引用。如果您正在用一個WEB 框架,可以把SqlSession 的作用域看作類似
於HTTP 的請求範圍。也就是說,在收到一個HTTP 請求,您可以開啟一個SqlSession,當您把
response 返回時,就可以把SqlSession 關閉。關閉會話是非常重要的,您應該要確保會話在一
個finally 塊中被關閉。
 

SqlSession session = sqlSessionFactory.openSession();
try {
    // do work
} finally {
    session.close();
}
在您的程式碼裡都使用這一模式將保證所有的資料庫資源被正確地關閉(假如您沒有把您自己
的資料庫連線傳遞給MyBatis 管理,這就對MyBatis 表明您希望自己管理連線)。

Mapper 例項

 
Mappers 是建立來繫結對映語句的介面,該Mapper 例項是從SqlSession 得到的。因此,所
有mapper 例項的作用域跟建立它的SqlSession 一樣。但是,mapper 例項最好的作用域是
method,也就是它們應該在方法內被呼叫,使用完即被銷燬。並且mapper 例項不用顯式地被關
閉。雖然把mapper 例項保持在一個request 範圍(與SqlSession 相似)不會產生太大的問題,
但是您可能會發現,在這個層次上管理太多資源可能會失控。保持簡單,就是讓Mappers 保持在
一個方法內。下面的例子演示了這種做法。
 

SqlSession session = sqlSessionFactory.openSession();
try {
    BlogMapper mapper = session.getMapper(BlogMapper.class);
    // do work
} finally {
    session.close();
}




相關文章