跳到主要內容

Mybatis精講(二)---生命周期

目錄


















回顧



  • 上一章節我們通過xml和代碼的方式實現了Mybatis環境的配置。代碼方式只是簡單介紹下。我們也知道我們大部分情況使用的是xml方式的配置。在實際開發中我們那樣開發顯然是不合理的。


  • 上章節提到的組件显示不可能每次執行sql都要重新創建的。這樣性能上肯定是過不去的。今天我們就來簡單聊聊SqlSessionFactoryBuilder、SqlSessionFactory、SqlSession、Mapper這些組件的生命周期吧。




SqlSessionFactoryBuilder



  • 通過觀察分析這個類我們就知道既然是Builder模式的類,那他的作用就是構建起(孵化器).換句話說這個類不是那麼的重要,因為他唯一的作用就是孵化SqlSessionFactory。在Spring與Mybatis整合的框架中,我相信Spring一定是在構建了SqlSessionFactory之後就將這個類進行回收了。因為後面就不需要了。這裏純屬個人猜想。



public SqlSessionFactory build(InputStream inputStream, String environment, Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}


  • 上面就是我們通過加載xml配置文件的源碼。我們不難發現build核心是通過XMLConfigBuilder這個類去負責解析mybatis-config.xml配置文件並生成Configuration對象。


SqlSessionFactory



  • 看名字就知道是工廠模式。在這裏我們可以把他看成數據庫連接池。既然是工廠就肯定得有產品。SqlSessionFactory的產物就是SqlSession。SqlSession是與數據庫的一次連接。管理數據庫的連接的自然就是連接池了。

  • Mybatis中使用的SqlSessionFactory是DefaultSqlSessionFactory 。 以連接池的角度看待我們不難推斷出SqlSessionFactory應該是個單例 。SqlSessionFactory對應的是數據庫。一個數據庫原則上應該對應一個SqlSessionFactory來管理。這點在Spring中正好無縫連接。把SqlSessionFactory交由spring管理。spring默認是單例模式bean.


openSessionFromDataSource



  • SqlSessionFactory通過openSession方法獲取SqlSession.SQLSession實際上可以看做是一次數據庫的連接。下面我們通過源碼的方式去看看工廠是如何生產SqlSession的。


<!--定義數據庫信息,默認使用development數據庫構建環境-->
<environments default="development">
<environment id="development">
<!--jdbc事物管理-->
<transactionManager type="JDBC"></transactionManager>
<!--配置數據庫連接信息-->
<dataSource type="POOLED">
<property name="driver" value="${database.driver}"/>
<property name="url" value="${database.url}"/>
<property name="username" value="${database.username}"/>
<property name="password" value="${database.password}"/>
</dataSource>
</environment>
</environments>


private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
//定義一個事物對象
Transaction tx = null;
try {
//通過配置對象獲取事先配置好的環境對象 這裏對應了xml中的environments標籤 。environments默認develop.所以是develop的environment
final Environment environment = configuration.getEnvironment();
//通過環境獲取事物。在environment里配置了JDBC類型的事物==JdbcTransactionFactory;如果沒有配置則默認採用ManagedTransactionFactory
final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
//構建事物對象 , 實際就是屬性的賦值
tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
//獲取執行器 BatchExecutor、ReuseExecutor、SimpleExecutor , 選擇SimpleExecutor
//因為默認有緩存,這裡會用CachingExecutor包裹原始Executor , 之後會加載各種插件
final Executor executor = configuration.newExecutor(tx, execType);
//返回DefaultSqlSession。寫死
return new DefaultSqlSession(configuration, executor, autoCommit);
} catch (Exception e) {
closeTransaction(tx); // may have fetched a connection so lets call close()
throw ExceptionFactory.wrapException("Error opening session. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}

Executor



  • Mybatis的數據庫執行器。Mybatis提供了一共四中Executor.這裏嚴格意義上應該說是三種 BatchExecutor、ReuseExecutor、SimpleExecutor。還有一個CachingExecutor。這裏為什麼不把他算上了。因為這個是一個全局的開關。在settings標籤的cacheEnabled設置的。說道這個標籤大家都知道這個就是二級緩存的開關。所以這裏CachingExecutor就不做介紹了。

  • SimpleExecutor是一種常規執行器,每次執行都會創建一個statement,用完后關閉。

  • ReuseExecutor是可重用執行器,將statement存入map中,操作map中的statement而不會重複創建statement。

  • BatchExecutor是批處理型執行器,doUpdate預處理存儲過程或批處理操作,doQuery提交並執行過程。

  • 關於Executor的選取也是在settings標籤控制的。defaultExecutorType。 默認是simple


SqlSession



  • 每個線程都有一個屬於自己的Sqlsession對象。這裏我們看成是一次Connection。他的生命周期應該是一次完成的事物處理過程。他是一個線程不安全的對象。在多線程操作的時候我們需要注意事物的隔離級別。我們操作時需要注意的是每次處理玩需要將他關閉。否則會造成資源浪費。在Mybaits中已經通過finnally把我們將他釋放了。


Mapper



  • Mapper是一個接口,我們可以將xml看成他的一個實現類。這裏的實現類虛化。通過Java代碼的調用實際將xml對應的sql發送給數據庫並獲取數據結果。



public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
}
try {
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception e) {
throw new BindingException("Error getting mapper instance. Cause: " + e, e);
}
}


  • 通過上述代碼我們能夠發現。在獲取Mapper的時候先通過類型看是否被註冊了。然後根據類別獲取代理實例。


總結



  • 關於生命周期其實沒什麼重點。這一章節也比較簡單。我們只需要知道我們最終需要的Mapper。然後是如何從配置到獲取Mapper.這過程中哪些是全局的。哪些又適合做成復用的。



# 加入戰隊


微信公眾號


本站聲明:網站內容來源於博客園,如有侵權,請聯繫我們,我們將及時處理

【其他文章推薦】

※專營大陸空運台灣貨物推薦



台灣空運大陸一條龍服務



※評比彰化搬家公司費用,南投搬家公司費用收費行情懶人包大公開



彰化搬家費用,南投搬家費用,距離,噸數怎麼算?達人教你簡易估價知識!




Orignal From: Mybatis精講(二)---生命周期

留言

這個網誌中的熱門文章

Python 併發總結,多線程,多進程,異步IO

1 測量函數運行時間 import time def profile(func): def wrapper(*args, ** kwargs): import time start = time.time() func( *args, ** kwargs) end = time.time() print ' COST: {} ' .format(end - start) return wrapper @profile def fib(n): if n<= 2 : return 1 return fib(n-1) + fib(n-2 ) fib( 35 )   2 啟動多個線程,並等待完成   2.1 使用threading.enumerate() import threading for i in range(2 ): t = threading.Thread(target=fib, args=(35 ,)) t.start() main_thread = threading.currentThread() for t in threading.enumerate(): if t is main_thread: continue t.join()   2.2 先保存啟動的線程 threads = [] for i in range(5 ): t = Thread(target=foo, args= (i,)) threads.append(t) t.start() for t in threads: t.join()   3 使用信號量,限制同時能有幾個線程訪問臨界區 from threading import Semaphore import time sema = Semaphor...

高雄十大包子名店出爐

, 圖文:吳恩文 高雄包子大賽落幕了,我只能就我個人意見, 介紹一下前十名這些包子,但是不能代表其他四位評審的意見,雖然身為評審長,我通常不會第一個表示意見,以免影響其他評審, 我主要工作是負責發問。   這次參賽的素包子很少,而且都不夠細致,又偏油,我不愛, 但是第一名的甜芝麻包-熔岩黑金包,竟然是素食得名- 漢來蔬食巨蛋店。   這包子賣相太好,竹炭粉的黑色外皮刷上金粉,一上桌,眾人驚呼, 搶拍照,內餡是芝麻餡,混一點花生醬增稠,加入白糖芝麻油, 熔岩爆漿的程度剛剛好,我一直以為芝麻要配豬油才行、 但是選到好的黑芝麻油一樣不減香醇, 當下有二位評審就想宅配回家。   尤其特別的是,黑芝麻餡室溫易化,師傅必須要輪班躲在冷藏室內, 穿著大外套才能包,一天包不了多少,我笑說,漢來美食,集團餐廳那麼多,實力雄厚,根本是「 奧運選手報名參加村裡運動會」嘛,其他都是小包子店啊, 但是沒辦法,顯然大家都覺得它好看又好吃, 目前限定漢來蔬食高雄巨蛋店,二顆88元,可以冷凍宅配, 但是要排一陣子,因為供不應求,聽說,四月份, 台北sogo店開始會賣。   第二名的包子,左營寬來順早餐店,顯然平易近人的多,一顆肉包, 十塊錢,是所有參賽者中最便宜的,當然,個頭也小, 它的包子皮明顯和其他不同,灰灰的老麵,薄但紮實有嚼勁, 肉餡新鮮帶汁,因為打了些水,味道極其簡單,就是蔥薑,塩, 香油,薑味尤其明顯,是老眷村的味道, 而特別的是老闆娘是台灣本省人, 當年完全是依據眷村老兵的口味一步一步調整而來,沒有加什麼糖、 五香粉,胡椒粉,油蔥酥。就是蔥薑豬肉和老麵香,能得名, 應該是它的平實無華,鮮美簡單,打動人心。   這是標準的心靈美食,可以撫慰人心,得名之前,寛來順已經天天排隊,現在,恐怕要排更久了, 建議大家六七點早點上門。   第三名,「專十一」很神奇,我記得比賽最後, 大家連吃了幾家不能引起共鳴的包子,有些累,到了專十一, 就坐著等包子,其他評審一吃,就催我趕快試,我一吃, 也醒了大半。   它的包子皮厚薄適中,但是高筋麵粉高些,老麵加一點點酵母, 我心中,它的皮屬一屬二,至於餡又多又好吃,蛋黃還是切丁拌入, 不是整顆放,吃起來「美味、均衡、飽滿」。一顆二十元。   老闆是陸軍專科十一期畢業取名專十一,...

韋伯連續劇終於更新 期待第一季順利完結

  地球天文學界的跳票大王詹姆斯·韋伯空間望遠鏡 (James Webb Space Telescope,縮寫為 JWST)自 1996 年以來斷斷續續不按劇本演出的連續劇終於讓焦慮的觀眾們又等到了一次更新:五層遮陽罩測試順利完成。 裝配完成的韋伯望遠鏡與好夥伴遮陽罩同框啦。Credit: NASA   嚴格的測試是任何空間任務順利成功的重中之重。遮陽罩,這個韋伯望遠鏡異常重要的親密夥伴,要是無法正常運轉的話,韋伯的這一季天文界連續劇說不準就要一直拖更了。   詹姆斯·韋伯空間望遠鏡是歷史上造出的最先進的空間望遠鏡。它不僅是一架紅外望遠鏡,還具有特別高的靈敏度。但想要達到辣么高的靈敏度來研究系外行星和遙遠的宇宙童年,韋伯童鞋必須非常"冷靜",體溫升高的話,靈敏度會大大折損。這個時候,遮陽罩就要大顯身手啦。   遮陽罩在韋伯的設計中至關重要。韋伯望遠鏡會被發射到拉格朗日 L2 點,運行軌道很高,遠離太陽、地球與月球。太陽是韋伯的主要熱量干擾的來源,其次是地球與月球。遮陽罩會有效阻斷來自這三大熱源的能量並保護韋伯維持在工作溫度正常運轉。這個工作溫度指的是零下 220 攝氏度(-370 華氏度;50 開爾文)。 上圖中我們可以看出,韋伯望遠鏡的配置大致可分為兩部分:紅色較熱的一面溫度為 85 攝氏度,藍色較冷的一面溫度達到零下 233 攝氏度。紅色的這部分中,儀器包括太陽能板、通信設備、計算機、以及轉向裝置。藍色部分的主要裝置包括鏡面、探測器、濾光片等。Credit: STSci.   遮陽罩的那一部分和望遠鏡的鏡面這部分可以產生非常極端的溫差。遮陽的這面溫度可以達到 110 攝氏度,足以煮熟雞蛋,而背陰處的部分溫度極低,足以凍結氧氣。   工程師們剛剛完成了五層遮陽罩的測試,按照韋伯在 L2 時的運行狀態安裝了遮陽罩。L2 距離地球約 160 萬公里。NASA 表示這些測試使用了航天器的自帶系統來展開遮陽罩,測試目前都已成功完成。韋伯望遠鏡遮陽罩負責人 James Cooper 介紹說這是遮陽罩"第一次在望遠鏡系統的电子設備的控制下展開。儘管這個任務非常艱巨,難度高,但測試順利完成,遮陽罩展開時的狀態非常驚艷"。   遮陽罩由五層 Kapton 製成。Kapton 是一種聚酰亞胺薄膜材料, 耐高溫絕...