1. 程式人生 > 實用技巧 >2.3MyBatis三巨頭介紹作用域(Scope)和生命週期和對映器

2.3MyBatis三巨頭介紹作用域(Scope)和生命週期和對映器

2.3MyBatis三巨頭介紹作用域(Scope)和生命週期

為什麼要理解生命週期?

  • 理解我們之前討論過的不同作用域和生命週期類別是至關重要的,因為錯誤的使用會導致非常嚴重的併發問題。

物件生命週期和依賴注入框架

  • 依賴注入框架可以建立執行緒安全的、基於事務的 SqlSession 和對映器,並將它們直接注入到你的 bean 中,因此可以直接忽略它們的生命週期。 如果對如何通過依賴注入框架使用 MyBatis 感興趣,可以研究一下 MyBatis-Spring 或 MyBatis-Guice 兩個子專案。

2.3.1 SqlSessionFactoryBuilder

  • 這個類可以被例項化、使用和丟棄,一旦建立了 SqlSessionFactory,就不再需要它了。

    因此 SqlSessionFactoryBuilder 例項的最佳作用域是方法作用域(也就是區域性方法變數)。 你可以重用 SqlSessionFactoryBuilder 來建立多個 SqlSessionFactory 例項,但最好還是不要一直保留著它,以保證所有的 XML 解析資源可以被釋放給更重要的事情。

2.3.2 SqlSessionFactory

  • SqlSessionFactory 一旦被建立就應該在應用的執行期間一直存在,沒有任何理由丟棄它或重新建立另一個例項。 使用 SqlSessionFactory 的最佳實踐是在應用執行期間不要重複建立多次,多次重建 SqlSessionFactory 被視為一種程式碼“壞習慣”。因此 SqlSessionFactory 的最佳作用域是應用作用域

    。 有很多方法可以做到,最簡單的就是使用單例模式或者靜態單例模式。

2.3.3 SqlSession

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

2.4 對映器

對映器例項

  • 對映器是一些繫結對映語句的介面。對映器介面的例項是從 SqlSession 中獲得的。

  • 雖然從技術層面上來講,任何對映器例項的最大作用域與請求它們的 SqlSession 相同。但方法作用域才是對映器例項的最合適的作用域。

  • 也就是說,對映器例項應該在呼叫它們的方法中被獲取,使用完畢之後即可丟棄。

  • 對映器例項並不需要被顯式地關閉。儘管在整個請求作用域保留對映器例項不會有什麼問題,但是你很快會發現,在這個作用域上管理太多像 SqlSession 的資源會讓你忙不過來。

  • 因此,最好將對映器放在方法作用域內。

try (SqlSession session = sqlSessionFactory.openSession()) {
BlogMapper mapper = session.getMapper(BlogMapper.class);
// 你的應用邏輯程式碼
}