1 背景
這是一個安靜祥和沒有bug的下午,
作為一只菜雞,時刻鞏固一下基礎還是很有必要的,如此的大好時機,就讓我來學習學習mybatis如何使用,

這可和我看到的不一樣啊,讓我來看看專案里怎么寫的,

我們專案中的Dao都繼承于BaseDao,而BaseDao繼承于SqlSessionDaoSupport,每次執行sql的時候都是直接將這個sqlSession回傳,然后執行sql,這難道不是一個實體變數嘛?這和你說的可不一樣誒,于是帶著這樣的疑問,我開始了探索,
2 探索之旅
1)我們都知道,在使用mybatis時,sqlSession都來自于sqlSessionFactory,而sqlSessionFactory可以通過sqlSessionFactoryBuilder創建,也可以通過spring初始化,而專案中很顯然采取了后一種方式,

2)那么我們已經得到了sqlSessionFactory,應該如何去進一步探索sqlSession的來源呢,我想到可以通過專案中已經實作的dao進行探索,我們隨便選取一個dao為例,

它繼承了BaseDao,

而BaseDao又繼承了SqlSessionDaoSupport,在BaseDao中呼叫了getSqlSession方法,實際上也就是SqlSessionDaoSupport的getSqlSession方法,

而SqlSessionDaoSupport的getSqlSession方法是直接將自己的成員變數回傳去的,截至目前為止,和我的懷疑點是相符合的,即目前的寫法和mybatis官網的說明是沖突的,
3)反復閱讀SqlSessionDaoSupport這個類后,終于被我發現了線索,細心的小伙伴應該也早已發現了,就在上圖之中的注釋中,“用戶應該使用這個方法來獲得一個SqlSession來執行sql陳述句,這個SqlSession被spring管理,用戶不應該提交、回滾或關閉它,因為這些已經被自動執行了,”
同時,這個方法會回傳一個執行緒安全的SqlSession,

那么這個SqlSession是從何而來的呢,從上圖可以看出,它有兩種賦值方式,一種是給他傳一個SqlSessionFactory,生成SqlSessionTemplate,SqlSessionTemplate即為sqlSession,另一種是直接給他傳一個SqlSessionTemplate作為SqlSession,根據本類的注釋,如果SqlSessionFactory和SqlSessionTemplate都被定義了,那么SqlSessionFactory的方式會失效,至此,我的上述疑問已經解決了,也就是說這個SqlSession并不是一個mybatis初始的SqlSession,而是spring實作的SqlSessionTemplate,
4)但是,我又誕生了新的疑問,SqlSessionTemplate是怎么完成執行緒安全的呢?

于是我進入了SqlSessionTemplate的方法執行,發現實際執行陳述句的都是這個代理類sqlSessionProxy,

而代理作業內容就在SqlSessionInterceptor這個handler里,

進入其中,我們終于發現了它的獲取和關閉操作,


也就是說,每次執行,代理都會呼叫sessionFactory的openSession方法獲得一個新的session,
3 總結
終于的終于,mybatis,spring,專案以及我的疑問得到了統一,真是一個寧靜祥和而又沒有bug的下午呀,
作者:馬躍
轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/538056.html
標籤:其他
上一篇:關于你的密碼安全和隱私安全
下一篇:第一次打靶
