MyBatis 作用域(Scope)和生命週期

原文鏈接:http://www.mybatis.org/mybatis-3/zh/index.html

不同作用域和生命週期類是至關重要的,因爲錯誤的使用會導致非常嚴重的併發問題

SqlSessionFactoryBuilder

這個類可以被實例化、使用和丟棄,一旦創建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 實例的最佳作用域是方法作用域(也就是局部方法變量)。 你可以重用 SqlSessionFactoryBuilder 來創建多個 SqlSessionFactory 實例,但是最好還是不要讓其一直存在,以保證所有的 XML 解析資源可以被釋放給更重要的事情

 

 

SqlSessionFactory

SqlSessionFactory 一旦被創建就應該在應用的運行期間一直存在,沒有任何理由丟棄它或重新創建另一個實例。 使用 SqlSessionFactory 的最佳實踐是在應用運行期間不要重複創建多次,多次重建 SqlSessionFactory 被視爲一種代碼“壞味道(bad smell)”。因此 SqlSessionFactory 的最佳作用域是應用作用域。 有很多方法可以做到,最簡單的就是使用單例模式或者靜態單例模式。

 

SqlSession

每個線程都應該有它自己的 SqlSession 實例。SqlSession 的實例不是線程安全的,因此是不能被共享的,所以它的最佳的作用域是請求或方法作用域。 絕對不能將 SqlSession 實例的引用放在一個類的靜態域,甚至一個類的實例變量也不行。 也絕不能將 SqlSession 實例的引用放在任何類型的託管作用域中,比如 Servlet 框架中的 HttpSession。 如果你現在正在使用一種 Web 框架,要考慮 SqlSession 放在一個和 HTTP 請求對象相似的作用域中。 換句話說,每次收到的 HTTP 請求,就可以打開一個 SqlSession,返回一個響應,就關閉它。 這個關閉操作是很重要的,你應該把這個關閉操作放到 finally 塊中以確保每次都能執行關閉。 下面的示例就是一個確保 SqlSession 關閉的標準模式:

 

try (SqlSession session = sqlSessionFactory.openSession()) {

  // 你的應用邏輯代碼}

在你的所有的代碼中一致地使用這種模式來保證所有數據庫資源都能被正確地關閉。

映射器實例

映射器是一些由你創建的、綁定你映射的語句的接口。映射器接口的實例是從 SqlSession 中獲得的。因此從技術層面講,任何映射器實例的最大作用域是和請求它們的 SqlSession 相同的。儘管如此,映射器實例的最佳作用域是方法作用域。 也就是說,映射器實例應該在調用它們的方法中被請求,用過之後即可丟棄。 並不需要顯式地關閉映射器實例,儘管在整個請求作用域保持映射器實例也不會有什麼問題,但是你很快會發現,像 SqlSession 一樣,在這個作用域上管理太多的資源的話會難於控制。 爲了避免這種複雜性,最好把映射器放在方法作用域內。下面的示例就展示了這個實踐:

 

try (SqlSession session = sqlSessionFactory.openSession()) {

  BlogMapper mapper = session.getMapper(BlogMapper.class);

  // 你的應用邏輯代碼}

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